Let me start of by suggesting you take a few minutes and read Laerte Junior’s excellent blog
entry Exceptional PowerShell DBA Pt1 Orphaned Users. Laerte does a great job describing the
scenario, the approach he took to solving it and then he included the scripts! Really good
stuff Laerte!
When I looked at Laerte’s code, I recognized one of my least favorite PowerShell V1isms:
$Object = New-Object PSObject $Object | add-member Noteproperty LineNumber $LineNumber $Object | add-member Noteproperty Date $TodayDate $Object | add-member Noteproperty ServerName $svr $Object | add-member Noteproperty DatabaseName $Database $Object | add-member Noteproperty UserName $user.name $Object | add-member Noteproperty CreateDate $CreateDate $Object | add-member Noteproperty DateLastModified $DateLastModified $Object | add-member Noteproperty AsymMetricKey $user.AsymMetricKey $Object | add-member Noteproperty DefaultSchema $user.DefaultSchema $Object | add-member Noteproperty HasDBAccess $user.HasDBAccess $Object | add-member Noteproperty ID $user.ID $Object | add-member Noteproperty LoginType $user.LoginType $Object | add-member Noteproperty Login $user.Login $Object | add-member Noteproperty Orphan ($user.Login -eq "")
Gosh that is a horrible looking thing. This is one of the things we fixed with PowerShell V2 so you take a few minutes to
learn this so you never have to do that mess again. Let’s get some help:
PS> Get-Help New-Object -Parameter Property
-Property <hashtable>
Sets property values and invokes methods of the new object.
Enter a hash table in which the keys are the names of properties or methods and the values are property value
s or method arguments. New-Object creates the object and sets each property value and invokes each method in
the order that they appear in the hash table.
If the new object is derived from the PSObject class, and you specify a property that does not exist on the o
bject, New-Object adds the specified property to the object as a NoteProperty. If the object is not a PSObjec
t, the command generates a non-terminating error.
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters? false
Thats right – you can now specify a hashtable and we’ll set these as NoteProperties on an object. What that means is that you can now write code like this:
$Object = New-Object PSObject -Property @{ LineNumber = $LineNumber Date = $TodayDate ServerName = $svr DatabaseName = $Database UserName = $user.name CreateDate = $CreateDate DateLastModified = $DateLastModified AsymMetricKey = $user.AsymMetricKey DefaultSchema = $user.DefaultSchema HasDBAccess = $user.HasDBAccess ID = $user.ID LoginType = $user.LoginType Login = $user.Login Orphan = ($user.Login -eq "") }
or if you prefer:
$hash = @{ LineNumber = $LineNumber Date = $TodayDate ServerName = $svr DatabaseName = $Database UserName = $user.name CreateDate = $CreateDate DateLastModified = $DateLastModified AsymMetricKey = $user.AsymMetricKey DefaultSchema = $user.DefaultSchema HasDBAccess = $user.HasDBAccess ID = $user.ID LoginType = $user.LoginType Login = $user.Login Orphan = ($user.Login -eq "") } $Object = New-Object PSObject -Property $hash
This is SO much better than V1 – be sure to use it and to tell all your friends about it as well!
Experiment! Enjoy! Engage!
Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
Hi, firstly thats much nicer. But it's not ordered.I found that the second method worked by casting [ordered]:
#array = @()#hash table = @{}$outputwithadgroups = @() foreach ($employee in $csvMembersRoles){
$groups = Get-ADUser -Identity $employee.network_id -Properties memberof | select memberof #because this is an array we can build a csv export per groupforeach ($group in $groups.memberof){$hash = [ordered]@{network_id = $employee.network_id; role_id = $employee.role_id;role_title = $employee.role_title;ad_group = ((($group | Out-String).Split(',').TrimStart('CN='))[0]) }$out = New-Object PSObject -Property $hash$outputwithadgroups...
What if i want to specify the type of each property? Is there any feature supporting this?