Blog Archives

Reading ServersCheck Status page from command line – Part 2.

In the Part 1. of the article I showed command line tool written with Google Go that reads current values from ServersCheck temperature and humidity sensor. In part 2 of the article I’ll show you how I did the same with PowerShell 3.0 script. In a way this script is more sophisticated than the golang variant. First because of the way how password for ServersCheck is handled, instead of security by obscurity I’m asking user once for a password, then storing password encrypted with a combination of his/her computer private key + user session key in a local file vpctemp-pwd.txt. Not bullet proof but nevertheless a big improvement from golang version of the script.
Second, the way I parse xml in powershell is simplified, thanks to select-xml cmdlet built in powershell 3.0.

A prerequisite for running the script is:
– PowerShell 3.0 (hence .NET 4 framework is also needed)
– execution policy must be set to RemoteSigned

You can check PowerShell version with:

PS> get-host | select version

and execution policy with (make sure that you run PowerShell in Admin mode!):

PS> Get-ExecutionPolicy

and if it's not RemoteSigned change it with:

PS> Set-ExecutionPolicy RemoteSigned

Final result of the script is output similar to golang version:

ServersCheck03

And here is the powershell script source:

#
# vpctemp.ps1 - PowerShell 3.0 script
# by AlesK 
#
$version = "v0.10"
$uri = "http://10.10.10.1/retcurvalue.xml"
$username = "admin"
$pwdfile = ".\vpctemp-pwd.txt"

if (Test-Path $pwdfile) {
 $password = Get-Content $pwdfile | ConvertTo-SecureString
}
else {
 $password = Read-Host "Password for Admin" -AsSecureString
 $password | ConvertFrom-SecureString | Out-File $pwdfile
}

$credential = New-Object System.Management.Automation.PSCredential $username,$password

$result = Invoke-Webrequest -URI $uri -Credential $credential -UseBasicParsing

[xml]$xml = $result | select -expand Content 

$temp1 = $xml | select-xml -xpath '/retcurvalue/ssvalue0' | select -expand Node 
$temp2 = $xml | select-xml -xpath '/retcurvalue/ssvalue1' | select -expand Node 
$hum1  = $xml | select-xml -xpath '/retcurvalue/ssvalue2' | select -expand Node 
$timestamp = Get-Date

Write-Host "VPCtemp $version        Location: VPC1"
Write-Host "***********************************"
Write-Host "Timestamp     :", $timestamp
Write-Host "Temp. internal:", $temp1."#text"
Write-Host "Temp. external:", $temp2."#text" -foregroundcolor "yellow" -backgroundcolor "red"
Write-Host "Humidity      :", $hum1."#text"

In the final, part 3 of the article I’ll show you how we’re using Oracle external table “preprocessor” feature to display data center temperature and humidity with simple SQL statement.

Wake-On-Lan with PowerShell

Here is a code snippet from PowerShell script that I found on the net (thanks Brandon!) that actually works, as opposed to many examples I tried out that did not send magic packet correctly…

function Send-WOL{
    param ($macaddy)
    $mymac = $macaddy.split(':') | %{ [byte]('0x' + $_) }
    if ($mymac.Length -ne 6)
    {
        throw 'Mac Address Must be 6 hex Numbers Separated by : or -'
    }
    Write-Verbose "Creating UDP Packet"
    $UDPclient = new-Object System.Net.Sockets.UdpClient
    $UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000)
    $packet = [byte[]](,0xFF * 6)
    $packet += $mymac * 16
    Write-Verbose ([bitconverter]::tostring($packet))
    [void] $UDPclient.Send($packet, $packet.Length)
    Write-Host  "   - Wake-On-Lan Packet of length $($packet.Length) sent to $mymac"
}

…and here is an example:

PS E:\> Send-Wol(’70:f3:95:15:00:b5′)
– Wake-On-Lan Packet of length 102 sent to 112 243 149 21 0 181
PS E:\>

How to get SID with PowerShell

Here is simple example of how to retrieve local NT account (user or group) SID with powershell:

PS E:\TEST> $objUser = New-Object System.Security.Principal.NTAccount("alesk")
PS E:\TEST> $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
PS E:\TEST> $strSID.Value
S-1-5-21-1384281309-654973799-88281384-1000

To retrieve SID of domain user:

PS E:\TEST> $objUser = New-Object System.Security.Principal.NTAccount("acmedomain\alesk")
or
PS E:\TEST> $objUser = New-Object System.Security.Principal.NTAccount("acmedomain","alesk")

PS E:\TEST> $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
PS E:\TEST> $strSID.Value
S-1-5-21-2377153150-1065022559-2428809875-3485

I found this tip among tips published on MS Technet Windows PowerShell tips.

Finding last Logon time with PowerShell

I needed to find out last AD log-on time for a particular Active Directory user account on all our domain controllers. I already knew that it should not be particular difficult to come up with some PowerShell one-liner.

With some help aside by the Google, I finally came up with the statement that I liked and that is worthy of this note for my future reference:

PS>
PS>
PS> $username='alesk'
PS> Get-QADComputer -ComputerRole DomainController | foreach {(Get-QADUser -Service $_.Name -SamAccountName $username) | select Name, DisplayName, LastLogon, Path} | sort LastLogon
PS>

…and with the output similar to this one:

Name DisplayName LastLogon Path
---- ----------- --------- ----
alesk ales-k 07.08.2009 23:30:00 LDAP://acme-dc2.corp.com...
alesk ales-k 10.08.2009 11:21:57 LDAP://acme-dc1.corp.com...
alesk ales-k 10.08.2009 11:40:01 LDAP://acme-dc3.corp.com...
alesk ales-k 10.08.2009 15:20:25 LDAP://acme-dc4.corp.com...

The logic behind the script is simple:

1) get the list of all the DC’s from ActiveDirectory (Get-QADComputer -ComputerRole DomainController).

2) then query each domain controller (-Service $_Name) for the account passed as variable ($username) and then select the attributes that are needed with ith the select statement (use select * to examine the vast amount of attributes available for querying).

3) finally, I wanted the result to be sorted by LastLogon field.

Free PowerShell Commands for Active Directory

Only recently I stumble over Quest “ActiveRoles Management Shell for Active Directory”, a free cmdlets for scripting with AD as a source (and destination). For example, all you need to spool users with their descriptions from AD into csv file is this one liner:

[PS] E:\>Get-QADUser -sizeLimit 0 | select name, Description | Export-Csv ADusers.csv

In addition to “ActiveRoles Management Shell for Active Directory”, you’ll need to install PowerShell itself and Microsoft Core XML Services – if they’re not already installed on your machine (Quest installer will prompt you if that’s is the case).
In “Quest Software” program directory you’ll find link named “ActiveRoles Management Shell for Active Directory” which starts PowerShell.

One problem that I could not find a solution for, is related to spooled file encoding which will loose all non-ASCII characters in my environment (CP1250 for GUI, CP852 for command prompt), even after specifying UTF8 encoding like this:

[PS] E:\>Get-QADUser -sizeLimit 0 | select name, Description | Export-Csv ADusers.csv
[PS] E:\>$OutputEncoding

BodyName          : utf-8
EncodingName      : Unicode (UTF-8)
HeaderName        : utf-8
WebName           : utf-8
WindowsCodePage   : 1200
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 65001

I also tried with console encoding:

[PS] E:\>$OutputEncoding = [console]::OutputEncoding
[PS] E:\>$OutputEncoding


IsSingleByte      : True
BodyName          : ibm852
EncodingName      : Central European (DOS)
HeaderName        : ibm852
WebName           : ibm852
WindowsCodePage   : 1250
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : False
IsMailNewsSave    : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 852

No luck – in .csv file all “special” characters are lost.