Category Archives: Scripting

Monitoring Storage disk queue’s and IO with PowerShell

/wp-content/uploads/2011/03/windows_powershell_icon.png?w=58&h=58&h=58Here’s one that used to bother me alot. The problem usually went as follows:

“Your XenApp servers have very high disk queue’s and IO”

“What’s causing it?”

“dunno…”

With Server 2008, the task manager’s resource monitor feature will help you find these items. But in server 2003 this was a perilous task. The specific details for disk io per process are stored in performance monitor under each specific process running. Trying to analyse each process was a massive pain, but powershell can do some very clever work to help alleviate this!

I wrote two quick functions which act similar to “top” in linux for giving an on screen view, updating at interval of what exactly is creating IO activity. These two functions are:

get-IODataBytes:

storageio

Get-IODataOperations

storageioops

The code for these functions are below:

[sourcecode language="powershell"]
function get-iodatabytes{
$result=(get-counter -counter "Process(*)IO Data Bytes/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Bytes/sec";Expression={[math]::Round($_.cookedvalue,0)}},@{Name="IO Data KBytes/sec";Expression={[math]::Round($_.cookedvalue / 1024,0)}} | sort -Descending "IO Data Bytes/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

FUnction get-IODataOperations {
$result=(get-counter -counter "Process(*)IO Data Operations/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Operations/sec";Expression={[math]::Round($_.cookedvalue,0)}} | sort -Descending "IO Data Operations/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

[/sourcecode]

if you wish to loop one of these functions, simply use the following code:

[sourcecode language="powershell"]
while ($true){
get-iodataoperations
start-sleep 1
}
[/sourcecode]

Silently installing the Citrix Edgesight ActiveX plugin

Just a really quick blog post on how to silently install the reporting agent inside your environment.

Log into a server / client without the EdgeSight plugin installed, and browse to the edgesight website. Once logged in, you will receive the usual prompt to install the software:

Install the software and ensure it works, then fire up a command prompt and browse down to “c:windowsdownloaded program files”. Once in this folder, a DIR will reveal the ActiveX plugin “csmdbprov.dll”.

Now simply copy this file out to shared storage:

Once done, now its scripting time!

Below are two examples in batch (.bat , .cmd) or PowerShell (.ps1) for achieving this:

(please amend h:csmdbprov.dll to the path you use)

Batch:

[sourcecode language="text"]
copy h:csmdbprov.dll "c:windowsdownloaded program files"
regsvr32 /s "c:windowsdownloaded program files"
[/sourcecode]

Powershell:

[sourcecode language="powershell"]
if (test-path h:csmdbprov.dll){
copy-item H:csmdbprov.dll ‘C:WindowsDownloaded Program Files’ -Force
start-process regsvr32 -ArgumentList "/s ""C:WindowsDownloaded Program Filescsmdbprov.dll""" -wait
}
[/sourcecode]

Retrieve a list of local administrators using Powershell.

Although a large number of scripts are available already for this job, most of them do not include an option to enumerate a remote machine.

My script uses WMI, allows you to query remote machines and returns objects for future use.

Thanks to my colleague Jason for the inspiration and help with this script!

function get-localadministrators {
    param ([string]$computername=$env:computername)

    $computername = $computername.toupper()
    $ADMINS = get-wmiobject -computername $computername -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computername',Name='administrators'""" | % {$_.partcomponent}

    foreach ($ADMIN in $ADMINS) {
                $admin = $admin.replace("$computernamerootcimv2:Win32_UserAccount.Domain=","") # trims the results for a user
                $admin = $admin.replace("$computernamerootcimv2:Win32_Group.Domain=","") # trims the results for a group
                $admin = $admin.replace('",Name="',"")
                $admin = $admin.REPLACE("""","")#strips the last "

                $objOutput = New-Object PSObject -Property @{
                    Machinename = $computername
                    Fullname = ($admin)
                    DomainName  =$admin.split("")[0]
                    UserName = $admin.split("")[1]
                }#end object

    $objreport+=@($objoutput)
    }#end for

    return $objreport
}#end function

get-localadministrators

retrieve an IBM servers serial number with Powershell.

We’ve all been there, we’ve a hardware call to log with a vendor, time is of the essence but yet, when they ask… we’ve forgotten to take down the serial number.

Here’s a few quick powershell one liners for getting the serial number using WMI.

I’ve tested this on IBM, and dell hardware but theres no reason it wont work on other systems.

Getting the local serial number:

get-wmiobject win32_bios | select-object serialnumber

Getting a remote serial number:

get-wmiobject win32_bios -computername remotecomputername | select-object serialnumber

I have a full self contained function after the jump should you wish to use it.

Continue reading

Exporting XenApp policys with powershell.

I needed to export our XenApp policies, as both a backup and a reference for an upcoming proof of concept involving XenApp 6. As no migration path is available, having the exported policies in a text document I can keep them open side by side while creating the new policies.

The following assumes your have the Xenapp Cmdlets installed and called.

foreach ($policy in get-xapolicy) {get-xapolicyconfiguration $policy.policyname | out-file “$env:temp$policy.txt”}

if you would prefer xml files:

foreach ($policy in get-xapolicy) {get-xapolicyconfiguration $policy.policyname | export-clixml “$env:temp$policy.xml”}

The above script dumps the policys in the chosen format to your temp folder. To auto jump to temp add “explorer $Env:temp” to the end of the line. E.G:

foreach ($policy in get-xapolicy) {get-xapolicyconfiguration $policy.policyname | export-clixml “$env:temp$policy.xml”} explorer $env:temp