Casting dates on the fly to sort with PowerShell

Yesterday I was approaced to help someone sorting some data using PowerShell. The data was in a CSV file with one of the fields, called “date”, containing a date & time that the data was going to be sorted on. Some of the dates were empty, but all of the ones that were populated were valid. The problem was that doing this didn’t work as expected:


Import-Csv file.csv | Sort-Object date


That’s because the objects being created and passed along the pipeline by Import-Csv contained the date as a string.


Now if you were going to do a lot of things with this data, you might want to be explicit about creating an object and importing the data into it, but in this case we were just sorting it and exporting to another CSV file, so there’s no need to go to that trouble.


The Sort-Object cmdlet doesn’t just accept properties as the parameter to sort by, you can give it a PowerShell script block. That means that as each object comes into Sort-Object, you can do things like casting types before they’re sorted. In this case it was as simple as:


Import-Csv file.csv | Sort-Object {$_.date -as [datetime]}


As I said before, some of those dates were empty, so they came out of the sort at the top, above the earliest proper date. That may be what you want, or it may not, but this makes it easy to do something about that. Say you wanted to set all the empty ones to the current date/time, your script block could look like this:


{Switch ($_.date){“” {Get-Date}}; $_.date -as [datetime]}


Just think of the possibilities!

Locating AD Computer Objects with PowerShell

Yesterday I was asked how you can find the locations of a list of computer objects in the Active Directory. Not an issue if all of your computers are in Computers, but we’ve got a structure of OUs that would put any ant colony to shame, so it’s a valid question.


My answer was as follows:


Put your list of machines in a file (c:\temp\machine.txt – one computer name per line) and depending on where you’re going to run this it’s a bit different. If you were on a Server 2008 R2 server which has the Active Directory cmdlets, then you need to do:


Get-Content c:\temp\machine.txt | Foreach-Object{
Get-ADComputer $_
} | Select-Object name,@{
name=”ou”;expression={
$_.distinguishedname.substring($_.name.length+4)
}
} | Format-Table -AutoSize


If not, I would suggest installing the AD cmdlets from Quest (http://www.quest.com/powershell/activeroles-server.aspx) and doing this:


Get-Content c:\temp\machine.txt | Foreach-Object{
Get-QADComputer $_
} | Select-Object name,parentcontainer | Format-Table –AutoSize



I’m just outputting to a table because I wasn’t told how the output was going to be used. You could use Export-Csv instead to pop it in a file. I should also point out that each of those examples works as a single line of code. I’ve just put it on different rows to stop my blog wrapping it in a confusing place – they’re actually pretty easy to read as a single line.


Now those are the ways that I would do it, but if you have to do something without the Microsoft or Quest AD cmdlets (if your environment is really locked down), all is not lost. This should work anywhere in your domain you can run PowerShell:


$ds = New-Object DirectoryServices.DirectorySearcher
$ds.SearchRoot=”LDAP://DC=yourdomain,DC=com”
Get-Content c:\temp\machine.txt | Foreach-Object{
$ds.Filter=”(&(objectclass=computer)(name=$_))”
$ds.FindOne() | Select-Object path

Finding IIS Application Pool States with PowerShell

Last night an attendee at NEBytes asked me how he can see the state of an application pool in IIS using PowerShell. I’m using IIS 7.5, but the first method is the way to do it in IIS 7.0 too…


Using the PowerShell provider you can browse through the components of IIS like you would the filesystem – it’s presented like a drive*, so you can do dir iis: to see the top level containers. To work with application pools, you can move into their container with cd iis:\AppPools after which a dir will list the app pools along with their states. For each of the application pools you’ll seeing a little bit of information as defined by the default formatting. You can see all the details of the first one with by piping to a formatting cmdlet, for example dir | Format-List *


That will give you the properties of the application pool, but not what you can do with it. Piping instead to Get-Member will tell you not only the properties of the object, but also the methods that it exposes, like start/stop/recycle.


New in IIS 7.5’s webadministration module for PowerShell are a set of cmdlets for working with IIS, including application pools. The cmdlet that answers the original question is Get-WebAppPoolState, and there are cmdlets for starting, stopping and recycling which are Start-WebAppPool, Stop-WebAppPool and Restart-WebAppPool (not recycle because PowerShell has a restriction on verbs in cmdlet names).


Those aren’t especially hard to remember, but if you wanted to know all of the cmdlets that relate to IIS application pools, you can do Get-Command *apppool*, or to see all of the commands in the webadministration module, Get-Command -PSSnapin  webadministration.


* Type Get-PSDrive to see what else has been presented in this way by the providers installed on your system.