Shutting down a lot of machines with Powershell.

A lot of my free time last year went into a book and one of the chapters in the book is about working with Active Directory from PowerShell. Version 1 leaves you with some work to do, and although we’re plugging this gap with Server 2008 R2 and PowerShell V2 you’ll need both, so I think some of my scripts will have a decent life. One of them is Get-DirectoryEntry

 Function Get-ADEntry

{param($Root=”” , [String]$Scope=”Subtree”, [String]$Filter)

 $Searcher = New-Object system.directoryServices.DirectorySearcher([adsi]$Root)

 $Searcher.SearchScope = $Scope

 If ($filter) {$Searcher.Filter = $Filter}

 $Searcher.findAll() | foreach-object {$_.GetDirectoryEntry()}}

 

I can use this to get all the computers in the current domain

 get-adentry -filter "(objectclass=computer)" 

Or just the ones in a specific container

 get-adentry -root LDAP://CN=Computers,DC=Roadshow,DC=com

 

At the Bett show Liam asked me if there was a way he could script shutting down all the workstations on his network. Well, assuming you can shut down all the machines in an OU, then you can pipe the output Get-ADEntry into something that calls shutdown.exe (or if you have V2 of PowerShell, the Stop-computer cmdlet) this takes quite a while to time out if the machine is off line,  so its best to ping the machines irst (V2, has a test-connection command, but I’d written Ping-Host already)

 Filter Ping-host {Param ($target, $server=“.” , [switch]$formatted ) If ($target –eq $null) {$target=$_} If ($target –is [Array] ){$target | forEach-Object {ping-Host –target $target –formatted:$formatted}} If ($target –is [string] ){$pingResult= Get-WmiObject -query `           "Select * from Win32_PingStatus where Address='$target' and ResolveAddressNames = True and recordRoute=1" If ($formatted) {$pingResult | Format-table –autosize –property Address,            ProtocolAddressResolved , ResponseTime , ResponseTimeToLive , StatusCode} Else                 {$pingResult}}}

So I ended up with a final command like this

 get-adentry -root LDAP://CN=Computers,DC=Roadshow,DC=com |

   forEach {if ((ping-host ($_.name[0])).StatusCode -eq 0) {shutdown.exe "/m" "\\$($_.name)" "/t" "300" "/s"}}

Pop the two functions in a PS1 file followed by as many instances of that as you have OUs to shutdown and your machines can be powered off in the evening or at any other time that takes your fancy. Just be careful where you point it !