Wednesday, September 10, 2014

Making those one liner scripts

Hey PowerShell users, do you love to script, but sometimes find yourself wishing that you just had a one liner to use instead of needing to copy or remotely execute a .ps1 file?

I was emailing back and forth with some colleagues at work recently, and one of our brilliant engineers had sent out this script to find the domain controller in the "closest" site that had the lowest latency. I don't know if he wrote it (he is certainly capable) or found it, but we all found it very useful:

 
$ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
$servers = Get-ADDomainController -Filter  {Site -eq $ADSite}
$DCListObject = New-Object psobject
$DCListObject | Add-Member -MemberType NoteProperty -Name HostName -Value $null
$DCListObject | Add-Member -MemberType NoteProperty -Name QueryTime -Value $null
$DCListObject | Add-Member -MemberType NoteProperty -Name Latency -Value $null
$results = @()
foreach ($server in $servers) {
    $DC = $DCListObject | Select-Object *
    $latency = Test-Connection -ComputerName $server -Count 1
    $querytime = Measure-Command -Expression { Get-ADObject -Server $latency.IPV4Address -LDAPFilter "(&(&(objectCategory=Person)(objectClass=User))(sAMAccountName=REMOVED*))" -ResultSetSize 1 -ErrorAction SilentlyContinue}

    $DC.HostName = $server.HostName
    $DC.QueryTime = $querytime.TotalSeconds
    $DC.Latency = $latency.ResponseTime

    $results += $DC
}
$results | sort QueryTime | ft HostName,Latency,QueryTime -AutoSize

Many remarks were made about the usefulness and coolness of the script, with the addition of one smart alecky response: "It's garbage. Make it one line :-)". This seems to be a running joke here.

Having just spent the last 16 months with a company full of penguin lovers at my last position, I responded with "Challenge accepted ;) maybe", even though I had not been the one challenged. About 8 minutes later (according to my email client), I sent the following back to the group:

$ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name ; $servers = Get-ADDomainController -Filter  {Site -eq $ADSite} ; $DCListObject = New-Object psobject ; $DCListObject | Add-Member -MemberType NoteProperty -Name HostName -Value $null ; $DCListObject | Add-Member -MemberType NoteProperty -Name QueryTime -Value $null ; $DCListObject | Add-Member -MemberType NoteProperty -Name Latency -Value $null ; $results = @() ; foreach ($server in $servers) {$DC = $DCListObject | Select-Object * ; $latency = Test-Connection -ComputerName $server -Count 1 ; $querytime = Measure-Command -Expression { Get-ADObject -Server $latency.IPV4Address -LDAPFilter "(&(&(objectCategory=Person)(objectClass=User))(sAMAccountName=REMOVED*))" -ResultSetSize 1 -ErrorAction SilentlyContinue} ; $DC.HostName = $server.HostName ; $DC.QueryTime = $querytime.TotalSeconds ; $DC.Latency = $latency.ResponseTime ; $results += $DC} ; $results | sort QueryTime | ft HostName,Latency,QueryTime –AutoSize

Worked great!

Two things, though. First, sure it's nice to be able to paste a one liner like this into PowerShell and run it with no need to create, save and possibly copy paste a .ps1 text file somewhere. But, secondly, who wants to try to decipher that hideousness?

In case it is not obvious to the reader, all I did in this case was, mostly, to separate each line in the script from the next one using a semicolon. The result is ugly but condensed to a single line that can be stored in your script repository for copy/paste use at any time. Don't ask your developers to look at it though, unless you enjoy that quizzical-what-kind-of-nonsense-am-I-looking-at expression. One other potential bad thing I noticed was that this one liner consistently ran a little slower than the .ps1 script.

Just goes to reinforce the old saying, "Just because you can does not mean you should."

But sometimes the question of "can" is just more fun.


"So that's your ambition? Script writing?" -- Mr. Fisher
 "Yes, it always has been." -- Billy



- Peter Trast, MCITP EA, MCITP DBA, MCT LinkIn with Peter

No comments:

Post a Comment