I was experimenting today with the PowerShell cmdlets for Citrix Provisioning Server. I was surprised to learn that the output of these cmdlets are not PowerShell types such as collections and objects with methods and properties but just plain text output.
A google search for a method to quickly convert the garbage output to objects led me to this blog post by Frank Peter. He describes a clever use of the switch statement with regular expressions with the Get-DiskInfo cmdlet.
Using Frank's code as a basis I wrote a generic function that converts Mcli output to an array of objects.
I slightly changed the regular expression for the name/value because my output was not indented.
Let's look at the code:
function ToObject {
param(
[Parameter(
Position=0,
Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)
]
[Alias('Command')]
[string]$cmd
)
$collection = @()
$item = $null
switch -regex (Invoke-Expression $cmd)
{
"^Record\s#\d+$"
{
if ($item) {$collection += $item}
$item = New-Object System.Object
}
"^(?<name>\w+):\s(?<value>.*)"
{
if ($Matches.Name -ne "Executing")
{
$item | Add-Member -Type NoteProperty -Name $Matches.Name -Value $Matches.Value
}
}
}
return $collection
}Usage Example:
"Mcli-Get Device" | ToObject | foreach {$_.deviceName}Please note that you need to pass the cmdlet and parameters to call as a string.
Glad to see you picking up my approach to transform mcli's text output to objects. Thanks FPS :)
Thank you for enabling us to properly use PowerShell with Citrix PVS.
There is a small "bug" in you function: the last item is never added to the collection. I've fixed this by added the item to the collection before before returning it.
So instead of:
return $collection
It now reads:
if ($item) {$collection += $item}
return $collection
Keep up the good work mate!
[…] If I use PowerShell to query the list of devices for the same group I get a different order even if I specially request a list sorted on deviceName. Consider the following example (note that I am using a function to convert McCli output ïnto Objects as documented here). […]
i was struggling with the formatting for Mcli output and your function is simply superb. 100 marks to your efforts.
$disks = 'Mcli-Get deviceinfo -p devicename=$sorteddevices' | ToObject
$sorteddisks = $disks | Sort-Object -Property @{Expression={[RegEx]::Match($_.deviceName, "(?:[a-zA-Z-\.]+)(?\d+)").Groups["number"].Value}}
$sorteddisks | Select-Object -Property diskLocatorName