Aug 12, 2016
Have you ever wanted to include the current date and/or time into your PowerShell scripts, maybe to timestamp your log entries, or to time just how long your scripts takes to run, or to include some date calculations for possible future scheduling options into your latest wizbang automation script? Well you struck paydirt, ‘cause today I will be expounding upon Data and Time Manipulations.
As we saw in my last blog (PowerShell Basics – Manipulating Strings), we saw that PowerShell works with .net objects, and the Date and Time functionality in PowerShell is the same - if we run a simple Get-Date | Get-Member we see here that the Get-Date cmdlet gets a DateTime object of type System.DateTime, that represents the current date and time. You can further use the –Format or the –Uformat (Unix format) parameters to output to an object type of System.String – very useful for sending on to other cmdlets or programs. System.DateTime has plenty of Properties to query, and even more Methods, too many to show here, but I just did a quick check on my Windows 10 PC and there are 13 Properties, 44 Methods, a NoteProperty and a ScriptProperty, so run the above command line for yourself to see them all for yourselves, and run Get-Help Get-Date –full to find out exactly what all those Methods and Properties etc. are for. Note that by default, the date-time output is displayed in long-date and long-time formats for the system locale to begin with, but we have lots and lots of formatting options.
So lets jump in with some examples:
Some nice easy ones to begin with: we start with just the Get-Date cmdlet, and in the 2nd example we also put the output of that cmdlet into a variable called $Today, so we can query some of the Properties and apply various Methods, such as to see the day of the week and then the year, take off days from the current date (using a negative parameter on the .AddDays Method) and so on. Then we display a short date format and then a short time format (although the methods are .ToShortDateString() and .ToShortTimeString() the outputs of these Methods actually convert to System.Array type). Last of all we have a test to see if we are in daylight savings time, followed by a count of the number of days in a year, up to the current time with the .DayofYear Method.
Again, as mentioned in previous blogs, note that Properties don't use parentheses ( ), but Methods do, and when we apply a Method to a variable, it changes the output of the cmdlet and not the actual contents of the variable, which remains the same.
So that was accessing the Get-Date methods and properties, now let’s have a look at the format parameters. As mentioned earlier, the –Format or the –Uformat (Unix format) parameters are used to output to an object type of System.String. The beauty of these two parameters is that they will output to a string type, making them ideal for various forms of output, but remember that they “filter out” everything except the actual values specified in the nominated format specifier. There is a rather large list of these format specifiers here. These format specifiers are not only case specific for most outputs, but the format specifier can be composed of single or multiple letters – i.e. “g”(general date & short time), “G” (general date & long time), “f” (full date and short time), “F” (full date & long time), “MMM” (abreviated month names), “MMMM” (full month names) etc. etc. But everything is not consistent here – sometimes upper and lower case characters will give the same result, and sometimes they will give a different result; you will just have to try them yourselves – or see the examples below.
-uFormat on the other hand tends to preceed its format parameters with a “%” symbol, but does give you a chance to drill down to a lot more specific identifiers (see the help file on the Get-Date cmdlet).
O.K., so that was Methods, Properties and Formats, but how do we input a date/time value into say a variable? One way is to pre-specify the variable type i.e. using what are called type accelerators. In the following example when I just assign a value to a variable, PowerShell normally assumes that whatever I enclose in the quotes is a string (you can use the .GetType () method to check), but I can “preconfigure” the variable as a DateTime object type by putting the accelerator option before the variable name. Of course this will only work if what is in the quotes can correctly be interpreted as a DateTime object type, otherwise an error will result.
Another common way to retrieve date/time values is use a WMI or CMI query. The first example uses CIM to query the local computer’s last start time and display it as a short date.
We can also use WMI for the same result, but WMI queries by default output to their own object type (called System.Management) whereas CIM can output directly to a DateTime type, so in the following example we have to use the WMI object’s ConvertToDateTime() Method to change the object type.
O.K. so 2 things to leave you with:
- The System.DateTime type includes Properties and Methods for working with “Ticks”. A “Tick” in this specific type (or class) represents 100 nanoseconds, or one ten-millionth of a second. Active Directory also uses “Ticks” representing 100 nanaseconds, but be careful here – The zero date in .NET framework (and therefore PowerShell) is 12:00am 1st January 0001 (there is no year 0000!), but the zero date in Active Directory is 12:00am 1st January 1601; a difference of 504,911,232,000,000,000 ticks! If you are using Ticks, make sure which system you are querying otherwise your results may be quite spectacularly different from what you are expecting! You can get more information, and tips on how to handle ticks in this Technet article:
- The following script (shown in PowerShell ISE) is the relevant parts of some scripts we run to configure our classroom images and in our labs, which I think is a great piece of PowerShell code to time your script executions – All my thanks to Microsoft!
See you soon for some more PowerShell Basics, tips and tricks.