When you work in the PowerShell console, exploring objects by piping them to Format-* cmdlets, outputted properties come out unsorted. One example is the [ADSI] type accelerator:
PS > [adsi]"" | format-list *
objectClass : {top, domain, domainDNS}
distinguishedName : {DC=domain,DC=com}
instanceType : {5}
whenCreated : {22/03/2001 09:11:41}
whenChanged : {23/08/2008 21:11:07}
(...)
So, how do you sort objects? You send the objects to Sort-Object cmdlet. But that won't help us here. Sort-Object sorts a COLLECTION of objects (based on a property name you provide) and we have just one object.
Aleksandar and I had little discussion about this and here is the final, quick and dirty function for the job.
function Sort-Member($inputObject,$memberType="*property",$name="*"){
begin{
$val = @{l='Value';e={$_.value}; align='left'}
}
process{
if($inputObject){ $_ = $inputObject }
$_ | foreach { $_.psobject.members.match($name,$memberType) | sort name | ft name,value -auto }
}
Basically, you need to construct a collection of the object properties and values and then pipe them to Sort-Object.
$object.psobject.members will give us the collection we need.
Sort-Member has three parameters:
-InputObject: This is the object you want its members to be sorted. You can use an array of objects too (e.g dir *.txt | Sort-Member).
-MemberType <PSMemberTypes>, Valid member types are: AliasProperty, CodeProperty, Property, NoteProperty, ScriptProperty, Properties, PropertySet, Method, CodeMethod, ScriptMethod, Methods, ParameterizedProperty, MemberSet, and All.
-Name: Supports wildcard matching on member names. It returns all members by default.
Sort-Member can take pipeline input:
PS > [adsi]"" | Sort-Member -name obj*
Name Value
---- -----
objectCategory {CN=Domain-DNS,CN=Schema,CN=Configuration,DC=domain,DC=com}
objectClass {top, domain, domainDNS}
objectGUID {1 253 0 145 0 42 234 77 146 251 209 191 23 113 20 247}
ObjectSecurity System.DirectoryServices.ActiveDirectorySecurity
objectSid {1 4 0 0 0 0 0 5 21 0 0 0 0 83 240 3 0 19 79 62 54 115 71 111}
or use the arguments:
PS > Sort-Member -input ([adsi]"") -name obj*
Name Value
---- -----
objectCategory {CN=Domain-DNS,CN=Schema,CN=Configuration,DC=domain,DC=com}
objectClass {top, domain, domainDNS}
objectGUID {1 253 0 145 0 42 234 77 146 251 209 191 23 113 20 247}
ObjectSecurity System.DirectoryServices.ActiveDirectorySecurity
objectSid {1 4 0 0 0 0 0 5 21 0 0 0 0 83 240 3 0 19 79 62 54 115 71 111}
Thanks to Harold Wong, Senior Technology Specialist at Microsoft, the whole series is now available for download as WMV files, Cheers Harold!!
I found a cool way HERE to shuffle/reorder array elements without using the random class.
Generally you provide Sort-Object an object property to sort on, only now the property is in the form of a Globally Globally Unique Identifier (GUID), which is a random generated 128-bit integer.
PS > 1..5 | sort-object { [guid]::newGuid() }
2
5
3
1
4
To select one or more random objects from the collection, pipe the above to Select-Object and use the -First (or -Last) parameter:
PS > 1..5 | sort-object { [guid]::newGuid() } | select-object -first 3
4
1
3
These techniques are also available on collections you use everyday with PowerShell, not just numbers. For instance, selecting 4 random lines from a text file (contain 10 numbered lines), you get the idea :-)
PS > Get-Content lines.txt | sort-object { [guid]::newGuid() } | select-object -last 4
Line 3
Line 4
Line 2
Line 5