Prof. Powershell

Give Me Time

PowerShell's DateTime object will leave you with time on your hands to do other things.

Last time we looked at methods for manipulating string objects. PowerShell's DateTime object has methods also for manipulating dates and times. You don't have to learn a bunch of VBscript-style functions or cmdlets. Instead, simply call the method or property you need. Let's start with a DateTime object and pipe it to Get-Member:

PS C:\> $d=get-date
PS C:\> $d | get-member

I think you'll see some items you can use immediately. For example, want to get the day of the week from $d? Use this:

PS C:\> $d.DayofWeek
Thursday

How easy is that? What about calculating a different datetime? In VBscript you might be used to the date-related functions. In PowerShell, simply call the method you need. To find the date time 47 days from $d call the AddDays() method:

PS C:\> $d.AddDays(47)

Tuesday, November 04, 2008 2:04:05 PM

Even thought there is a Subtract() method, I find it much easier to add a negative number to find a date time value in the past:

PS C:\> $d.AddDays(-47)

Saturday, August 02, 2008 2:04:05 PM

If you check the list from Get-Member, you'll see that you can add seconds, minutes, hours, days, months and years. The datetime object also includes methods for formatting. Here are some examples to give you an idea:

PS C:\> $d.ToShortDateString()
9/18/2008

PS C:\> $d.ToLongDateString()
Thursday, September 18, 2008

PS C:\> $d.ToLongTimeString()
2:04:05 AM

PS C:\> $d.ToShortTimeString()
2:04 AM

Let's look at one more practical application. My Get-AdminAge function looks at the administrator account on a given computer and returns the password age in days, calculates the date it was changed and the date it will expire:

Function Get-AdminAge {
  param([string]$computername=$env:computername,
  [string]$username="Administrator")

  [ADSI]$user="WinNT://$computername/$username,User"
  [int]$pwage=$user.passwordAge.value/86400
  [int]$pwmax=$user.maxpasswordage.value/86400
  [datetime]$now=Get-Date
  [datetime]$pwset=$now.AddDays(-$pwage)
  [datetime]$pwexpire=$pwset.AddDays($pwmax)

  $obj=New-Object PSObject

  $obj | Add-Member NoteProperty "Computer" $computername.toUpper()
  $obj | Add-Member NoteProperty "User" $username
  $obj | Add-Member NoteProperty "Age" $pwage
  $obj | Add-Member NoteProperty "PWSet" $pwset
  $obj | Add-Member NoteProperty "PWExpire" $pwexpire

  write $obj
}

The Password age and MaxpasswordAge properties are stored in seconds, so I convert them to days by dividing them by 86,400. Using the [DATETIME] object's AddDays() method, I can calculate the date the password was set by subtracting the password age from the current date and determine when the password will expire and adding the max password age value to the date the password was last set. No need for any fancy VBscript-like functions -- just a few simple method calls.

To see for yourself, load the function into your PowerShell session and call it:

PS C:\> get-adminage "Server01"
Computer : SERVER01
User : Administrator
Age : 19
PWSet : 9/2/2008 9:45:15 PM
PWExpire : 10/14/2008 9:45:15 PM

The function defaults to the local computername but you can specify a remote computer as I've done here.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular