Using PowerShell Object Methods
Get-Date helps you with date math, but its syntax is pretty weird
April 20, 2015
Most users doing even the simplest PowerShell scripting eventually need to consider time and dates. For example, recall that in “Search-ADAccount and the Missing 15 Days,” I attempted to answer the question, “Which user accounts haven’t logged on in the past 90 days?” I ended up using the Search-ADAccount PowerShell cmdlet to answer that question, but I could have formulated a “two-liner” using Where-Object, as in:
$LatestDay = [the date 90 days ago]get-aduser -filter * -properties * | where {$_.lastlogondate -le $LatestDay}
But how do you get a specific date “90 days ago”? A bit of research finds that this command would do the trick:
$LatestDay=((get-date).AddDays(-90))
Even if you’re not near Active Directory (AD), try the command from any PowerShell prompt and you’ll see Get-Date in action:
(get-date).AddDays(-90)
Honestly, I only knew that because I already understant a bit of .NET programming. Still, all that parenthetical stuff looks like an odd way to compel Get-Date to knock 90 days off today’s date. I mean, shouldn’t the syntax look something more like the following? (It doesn’t work, so don’t try it.)
get-date -AddDays -90
Virtually everyone whom I’ve taught PowerShell has the same reaction: “What’s with the parentheses?’’ Essentially, they exist because Get-Date is an old cmdlet—part of the PowerShell 1.0 arsenal—and because in those days the main folks thinking about PowerShell were really smart developers who thought in terms of object-oriented programming, and in particular .NET object-oriented programming.
Now, if you’ve never worked with object oriented coding, it sounds ugly but it’s really not that bad. The whole idea of object orientation is to make life easier for programmers. For example (and if there are any coders reading this, forgive me, because I’m about to vastly oversimplify things), let’s say you want to write some .NET code that manages your company’s payroll. The important “objects” in that scenario are employees, and they have many properties. Remember properties? We saw them with Get-Member, as in
get-aduser -filter * | get-member
Try that out, and you’ll see things like GivenName or Surname, which have a MemberType of Property. Look above them, and you’ll see some things that have a MemberType of Method instead of Property.
Anyway, even in a simple system, each employee object would have a name, email address, phone number, hire date, and hourly rate. That’s five properties, the first three of which are strings (just text information)—but strings with particular rules, as phone numbers only contain numbers, dashes, and parentheses … and, well, you know what email addresses look like. Then there’s the hire date, which is a datetime type of variable. (We’ve talked about those before, and they can’t be random, either, as no one has a hire date of March 76, 2417.) Finally, there’s the hourly rate, which is a floating-point number that also has constraints. (Most of us don’t make negative dollars per hour, even if it might seem that way sometimes!)
Now, whoever is programming this in my oversimplified .NET framework will need to include code to modify details about employees now and then, and he or she doesn’t want to have to worry about all of those validation details over and over again. Such a bit of code, called a method, would be glued on to the employee object. Supposing there’s a method on our employee object named “modify,” then perhaps it would need two inputs: which of the five properties to change, plus the new values. In a hybrid of oversimplified .NET-ese and PowerShell, it might look like this:
(get-employee Jack).modify(HourlyRate,36.10)
That would change Jack’s hourly wage to $36.10. This .NET-ish syntax made good sense to PowerShell’s early creators who, again, lived and breathed .NET, and that’s how Get-Date ended up as it did.
You can find Get-Date’s methods like so:
get-date | get-member
If you do that, you’ll see members of type Method, including AddDays, AddHours, and AddYears. You could, for example, find out the date and time 134 hours from now by typing
(get-date).AddHours(134)
So, the way to use methods is to type
(something that gets the original object).NameOfTheMethod(parameters for the method)
Get-Date got the current date. Then the method’s name was AddHours. I wanted to see 134 hours into the future, so the argument (the value passed to the method) was 134. Or you could make it a little more readable by typing two separate lines, as I did before:
$Now = get-date$Now.AddHours(134)
The most important question, however, is “How did I know that?” The short answer is I cheated a bit by reading the .NET documentation, which was partially the foundation of Get-Date. You can do that too, but I’ll cover that next month, when I’ll use PowerShell to talk to you. See you then!
About the Author
You May Also Like