Tied Variables in PowerShell

April 12, 2011


When PowerShell starts it creates a bunch of Automatic Variables. One of them is $PWD. $PWD contains a path object that represents the full path of the current directory (provider sensitive). Typically, when you assign a value to a variable, the value is evaluated once and from then on it’s “static”, each time you call the variable the returned value is always the same. The beauty of $PWD is that its value is calculated each time you call it.



PS > Set-Location HKLM:\SOFTWARE



$PWD contains a rich .NET object (System.Management.Automation.PathInfo), not just a string path, so we can also interact directly with its members:

PS > $PWD.Provider.Name


I was trying to create a variable similar to $PWD ($Now) to get the current date and time, but no matter what I tried, the value of $Now always returned the same date and time. The reason behind creating $Now was this. Let’s say you want to get the DayOfWeek value of a DateTime object, what we often do is:

## two lines of code
PS > $date  = Get-Date
PS > $date.DayOfWeek


## using a .NET class
PS> [DateTime]::Now.DayOfWeek


## enclosing in parenthesis
PS> (Get-Date).DayOfWeek


I wanted is to use the third example but avoid enclosing Get-Date it in parenthesis. One of the ways I was trying is with a function:

PS > function Now {Get-Date}

It works, I can now get a new fresh DateTime object each time I call the function, but I can’t access the result object members without enclosing it in parenthesis:

PS> (Now).DayOfWeek


Ultimately, this is how I wanted it to be:


Simple to use and very short to type. Another thought was to create a new Alias but the result was the same as using a function, parenthesis were required to access object members. So I posted a question to the PowerShell MVP private list and soon enough Lee Holmes, pointed me to this blog post. Here’s the code I used to create $Now:

Add-Type -TypeDefinition @”
using System;
using System.Management.Automation;
public class NowVariable : PSVariable
public NowVariable ()
  : base(“Now”, 0, ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope)
       public override object Value
               return DateTime.Now;

$ExecutionContext.SessionState.PSVariable.Set((New-Object -TypeName NowVariable))


Paste this code into your console and there you have it! A variable that evaluates its value each time you call it.

Tuesday, April 12, 2011 10:48:41 AM

Tuesday, April 12, 2011 10:48:43 AM

Tuesday, April 12, 2011 10:48:45 AM

PS> $Now.DayOfWeek


Now we can access any member of the result DateTime object without parenthesis. Thanks Lee! The next step is to ask the PowerShell team to include $Now in the next version of PowerShell and the way to do that is to file a suggestion on the Microsoft Windows PowerShell Customer Connection website. The PowerShell team review the items suggested by the community and if it has enough votes it will find its (hopefully) way to the next version of PowerShell.

Do you want to have $Now as a new automatic variable in PowerShell 3.0? Vote it up HERE.


UPDATE: Check out this awesome post, by Robert Robelo, where he shows a how to get the same functionality in pure script and it also works in PowerShell v1!


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



  1. cmcknz77May 5, 2011 ב 02:35

    I like it…
    I was thinking that I’d be able to do something similar to create an automatic variable for todays powershell.com tweettip:


    So that in my scripts I could just say:
    if($connectedtointernet){do {something cool}}

    But I can’t get it to work. I reckon I’m crossing language boundaries here right?

  2. ScriptFanaticMay 5, 2011 ב 18:03

    Yup, the code must be written in C#.

  3. Martin77September 2, 2011 ב 21:58

    A shorter way, would be to use a breakpoint when the $Now variable is being read, and set the variable’s new value using the action parameter.
    it adds up to:

    $global:Now = Set-PSBreakpoint -Variable Now -Mode Read -Action { Set-Variable Now (Get-Date) -Option ReadOnly, AllScope -Scope Global -Force }

  4. Maridsolar1985February 21, 2013 ב 08:53

    It is a pity, that now I can not express – it is compelled to leave. But I will return – I will necessarily write that I think on this question.