Problems using sort criteria

Hi, I'm a reader of the blog, but first time poster.

 

So I've been working a little with WMI queries, trying to stock-take our network, including which CPU's I've got.  As a result I'm using it as an excuse to get better with Powershell.  I created a script that queries different aspects of a server's information, and now would like to apply a sort field, with a unique option.


 

try {
Import-Module ActiveDirectory -ErrorAction Stop
} catch {
Write-Warning "Failed to import Active Directory module. Exiting"
return
}

$output

try {
$Hypervs = Get-ADObject -Filter 'ObjectClass -eq "serviceConnectionPoint" -and Name -eq "Microsoft Hyper-V"' -ErrorAction Stop
} catch {
Write-Error "Failed to query active directory. More details : $_"
return
}
foreach($Hyperv in $Hypervs) {

$temp = $Hyperv.DistinguishedName.split(",")
$HypervDN = $temp[1..$temp.Count] -join ","
$Comp = Get-ADComputer -Id $HypervDN -Prop *
$isvmhost = get-vmhost -ComputerName $comp.Name

if ($isvmhost -like "*vmhost")
{
$Comphw = Get-WmiObject win32_processor -ComputerName $comp.name
#$CPU_Model = ($comphw.name -match '(?:Xeon|Core).*?(?:i|e)\d\-\d{4}.{0,1}')
$OutputObj = [PScustomobject]@{
HyperVName = $Comp.Name
OSVersion = $comp.operatingSystem
CPU_Model = $Comphw.name
}

$OutputObj
}

}


 

So, the script above outputs precisely what I'm after.  But as you can see, I'm using a hash table to build my output.

The problem I have is that the output itself does not come in alphabetical order.  Now, of course, I could export the data to excel and manipulate it in there.  But it defeats my purpose of learning more about powershell.

 


Output:

 

HyperVName OSVersion CPU_Model
---------- --------- ---------
ATUIN               Windows Server 2012 R2 Datacenter            Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz
STEPUP              Windows Server 2012 R2 Datacenter           {Intel(R) Xeon(R) CPU X5450 @ 3.00GHz, Intel...
SUPPORT             Windows Server 2012 R2 Datacenter           {Intel(R) Xeon(R) CPU E5320 @ 1.86GHz, Intel...
GITS-TEST           Windows Server 2016 Datacenter TP5           Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz
FILESERVER          Windows Server 2012 R2 Datacenter           {Intel(R) Xeon(R) CPU E5530 @ 2.40GHz, Intel...

 


 

Ultimately, I'd like to change the output.  However, if I do something like:

 

$OutputObj | Sort-Object -Property unique

 

I get the following:

 


HyperVName OSVersion CPU_Model
---------- --------- ---------
ATUIN                Windows Server 2012 R2 Datacenter           Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz

STEPUP               Windows Server 2012 R2 Datacenter          {Intel(R) Xeon(R) CPU X5450 @ 3.00GHz, Intel...

SUPPORT              Windows Server 2012 R2 Datacenter          {Intel(R) Xeon(R) CPU E5320 @ 1.86GHz, Intel...

GITS-TEST            Windows Server 2016 Datacenter TP5          Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz

FILESERVER           Windows Server 2012 R2 Datacenter          {Intel(R) Xeon(R) CPU E5530 @ 2.40GHz, Intel...

BB-8                 Windows Server 2012 R2 Datacenter          {Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, Intel(R) Xe...

SOL                  Windows Server 2012 R2 Datacenter          {Intel(R) Xeon(R) CPU E5430 @ 2.66GHz, Intel...

 


Not very alphabetical.

 

So, my question is, where have I gone wrong?

  • Try Sort on the hash table, not the $OutputObj.

    As for your comment..

    'now would like to apply a sort field, with a unique option.'

    You do not say what you are looking for to be unique.
    If these are all VM's, then the CPU would be the same for them all, though the count could be different.
    Now, if you are saying that you are hitting different Hyper-V hosts with each having their own guests, then if the Hyper-V host are identical, then so woudl be the CPU nodel for all guests.
    Of course if the Hyper-V hosts are different, the the potatnial for the CPU to be diffent is there, but all the guest on each Hyper-V host woudl be the same CPU model (save counts) per host.
    So, you have only one CPU model for all your guest on similar host or only two CPU nodel for two Hyper-V hosts.



    This is not a valid line
    '$OutputObj | Sort-Object -Property unique'

    This should be
    $OutputObj | Sort-Object -Property '<SomeSortParam>' -Unique




    You are selecting 3 values to output. that alone, just because of the computer name / HyperVName (which must be unique anyway - because you cannot have duplicate computer names in ADDS of course), makes the each line in $OutputObj unique by default.

    It also looks like you are on W2K8 and a legacy PowerShell version, Hence the Import-Module ActiveDirectory thing. Later versions of PowerShell, as long as the RSAT ADDS tools are installed will do this auto-magically.

    You have also wayyyyy, over complicated the script for the use case you are after.
    Virtually all the above can be reduced to a few lines.

    for example, If I was doing this just hitting ADDS directly...
    (the same approach can be leverage at a VM-host where your guest reside of course.)



    Get-ADComputer -Filter 'Name -like "*vm*"' -Properties * |
    Select-Object Name, DNSHostName, OperatingSystem,
    @{Name = 'CPU_Model';Expression={(Get-WmiObject -Class Win32_Processor).Name}},
    @{Name = 'Manufacturer';Expression={(Get-WmiObject -Class Win32_ComputerSystem).Manufacturer}} |
    Format-Table -AutoSize


    Results

    Name DNSHostName OperatingSystem CPU_Model Manufacturer
    ---- ----------- --------------- --------- ------------
    USVM02 USVM02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM03 USVM03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM04 USVM04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM01 UKVM01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM01 USVM01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM03 UKVM03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM04 UKVM04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM02 UKVM02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM01 APVM01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM02 APVM02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM03 APVM03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM04 APVM04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.


    Get-ADComputer -Filter 'Name -like "*vm*"' -Properties * |
    Select-Object Name, DNSHostName, OperatingSystem,
    @{Name = 'CPU_Model';Expression={(Get-WmiObject -Class Win32_Processor).Name}},
    @{Name = 'Manufacturer';Expression={(Get-WmiObject -Class Win32_ComputerSystem).Manufacturer}} |
    Sort-Object Name |
    Format-Table -AutoSize


    Results

    Name DNSHostName OperatingSystem CPU_Model Manufacturer
    ---- ----------- --------------- --------- ------------
    APVM01 apvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM02 apvm02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM03 apvm03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    APVM04 apvm04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM01 ukvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM02 ukvm02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM03 ukvm03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UKVM04 ukvm04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM01 usvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM02 usvm02.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM03 usvm03.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    USVM04 usvm04.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.



    For sort - something has to be specified

    Get-ADComputer -Filter 'Name -like "*vm*"' -Properties * |
    Select-Object Name, DNSHostName, OperatingSystem,
    @{Name = 'CPU_Model';Expression={(Get-WmiObject -Class Win32_Processor).Name}},
    @{Name = 'Manufacturer';Expression={(Get-WmiObject -Class Win32_ComputerSystem).Manufacturer}} |
    Sort-Object -Property CPU_Model -Unique |
    Format-Table -AutoSize



    Of course the above would return zero results, since these are all virtual guests and the CPU_Model would be the same.

    Now, if I took that approach and trimmed the numbers off the Name and then selected Name -Unique


    Get-ADComputer -Filter 'Name -like "*vm*"' -Properties * |
    Select-Object @{Name ='HyperVName';Expression = {$_.Name -replace 'VM\d.','' }}, DNSHostName, OperatingSystem,
    @{Name = 'CPU_Model';Expression={(Get-WmiObject -Class Win32_Processor).Name}},
    @{Name = 'Manufacturer';Expression={(Get-WmiObject -Class Win32_ComputerSystem).Manufacturer}} |
    Sort-Object -Property HyperVName -Unique |
    Format-Table -AutoSize

    Results

    HyperVName DNSHostName OperatingSystem CPU_Model Manufacturer
    ---------- ----------- --------------- --------- ------------
    AP apvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    UK ukvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.
    US usvm01.contoso.com Windows Server 2012 R2 Standard Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz VMware, Inc.