The concept for this script was done before PowerShell V2 was released and provided better typing including 64 bit integers. Like in my older Perl and VBScript code dealing with Active Directory attributes that stored 64 bit integers like accountExpires, it required manipulating the return data in order to perform comparisons. The code below contains a Function written by Adam Weigert which has saved me the time translating the same conversion I've done before in Perl and VBScript. A link to his blog entry on the topic is commented in the code for your review.
param([string]$file) Function Get-DirectReports($objectDn, $distinguishedNames) { $distinguishedNames += $objectDn $managerObject = Get-ActiveDirectoryObject $objectDn if($managerObject.directReports.count -gt 0) { foreach($directReport in $managerObject.directReports) { $distinguishedNames = Get-DirectReports $directReport $distinguishedNames } } return $distinguishedNames } Function Read-UserStatus($userFlags) { if ($userFlags -band 0x0002) { $enabled = $false } else { $enabled = $true } return $enabled } Function Convert-ADSLargeInteger([object]$adsLargeInteger) { # http://weblogs.asp.net/adweigert/archive/2007/03/23/powershell-convert-active-directory-iadslargeinteger-to-system-int64.aspx $highPart = $adsLargeInteger.GetType().InvokeMember("HighPart", [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null) $lowPart = $adsLargeInteger.GetType().InvokeMember("LowPart", [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null) $bytes = [System.BitConverter]::GetBytes($highPart) $temp = [System.Byte[]]@(0,0,0,0,0,0,0,0) [System.Array]::Copy($bytes, 0, $temp, 4, 4) $highPart = [System.BitConverter]::ToInt64($temp, 0) $bytes = [System.BitConverter]::GetBytes($lowPart) $lowPart = [System.BitConverter]::ToUInt32($bytes, 0) return $lowPart + $highPart } Function Get-LocalDomainController($objectDomain) { return ([System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()).Servers | Where-Object { $_.Domain.Name -eq $objectDomain } | ForEach-Object { $_.Name } | Select-Object -first 1 } Function Get-ObjectADDomain($distinguishedName) { return ((($distinguishedName -replace "(.*?)DC=(.*)",'$2') -replace "DC=","") -replace ",",".") } Function Get-ActiveDirectoryObject($distinguishedName) { return [ADSI]("LDAP://" + (Get-LocalDomainController (Get-ObjectADDomain $distinguishedName)) + "/" + ($distinguishedName -replace "/","\/")) } #--------------------------------------------------------------------------------------------------# Set-Variable -name forestRootDn -option Constant -value ([ADSI]("LDAP://" + (([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).name) + "/rootDSE")).defaultNamingContext #--------------------------------------------------------------------------------------------------# if(![bool]$file) { Write-Host "You are missing the `"-file`" command line argument" -foregroundColor Red Write-Host "" Write-Host "This is the file that contains the list of employee e-mail addresses" Write-Host "" while((![bool]$file)) { $file = Read-Host -prompt "`tFile" } Write-Host "" } if(!(Test-Path -path $file)) { Write-Host "Unable to locate: $file" -foregroundColor Red Write-Host "" Write-Host "Please review the correct path" Write-Host "" while(!(Test-Path -path $file)) { $file = Read-Host -prompt "`tFile" } Write-Host "" } $answer = $null while($answer -ne "Y" -and $answer -ne "N") { $answer = Read-Host -prompt "Are you sure you want to use $file (Y/N)?" } if($answer -eq "N") { Write-Host "" Write-Host "Quiting..." -foregroundColor Yellow exit } $outputFile = (((Get-Item -path $file).name).Replace(((Get-Item -path $file).extension),".csv")) $managers = Get-Content -path $file $objectConnection = New-Object -comObject "ADODB.Connection" $objectCommand = New-Object -comObject "ADODB.Command" $objectConnection.Open("Provider=ADsDSOObject;") $objectCommand.ActiveConnection = $objectConnection $distinguishedNames = @() $users = @() foreach($manager in $managers) { $ldapBase = "GC://$forestRootDn" $ldapAttr = "distinguishedName" $ldapScope = "subtree" $ldapFilter = "(&(objectClass=user)(ProxyAddresses=smtp:$manager))" $ldapQuery= "<$ldapBase>;$ldapFilter;$ldapAttr;$ldapScope" $objectCommand.CommandText = $ldapQuery $objectRecordSet = $objectCommand.Execute() while(!$objectRecordSet.EOF) { $distinguishedNames = Get-DirectReports $objectRecordSet.Fields.Item('distinguishedName').Value $distinguishedNames $objectRecordSet.MoveNext() } } foreach($distinguishedName in $distinguishedNames) { $userObject = Get-ActiveDirectoryObject $distinguishedName if($userObject.objectClass -eq "User") { $accountExpires = (Convert-ADSLargeInteger $userObject.accountExpires[0]) if($accountExpires -ne 0 -and $accountExpires -ne 9223372036854775807) { $account_expiration = (Get-Date ($userObject.psbase.invokeget("AccountExpirationDate")) -Format d) } else { $account_expiration = "N/A" } if($userObject.manager) { $manager_object = Get-ActiveDirectoryObject $userObject.manager if($manager_object.displayName) { $manager = ($manager_object.displayName).ToString() } else { $manager = ($manager_object.name).ToString() } } else { $manager = "N/A" } $user = New-Object -typeName PSObject Add-Member -inputObject $user -type NoteProperty -name "domain" -value ((Get-ObjectADDomain $userObject.distinguishedName).Split(".")[0]).ToUpper() Add-Member -inputObject $user -type NoteProperty -name "sAMAccountName" -value (($userObject.sAMAccountName).ToString()).ToLower() Add-Member -inputObject $user -type NoteProperty -name "givenName" -value ($userObject.givenName).ToString() Add-Member -inputObject $user -type NoteProperty -name "sn" -value ($userObject.sn).ToString() Add-Member -inputObject $user -type NoteProperty -name "displayName" -value ($userObject.displayName).ToString() Add-Member -inputObject $user -type NoteProperty -name "mail" -value ($userObject.mail).ToString() Add-Member -inputObject $user -type NoteProperty -name "title" -value ($userObject.title).ToString() Add-Member -inputObject $user -type NoteProperty -name "department" -value ($userObject.department).ToString() Add-Member -inputObject $user -type NoteProperty -name "manager" -value $manager Add-Member -inputObject $user -type NoteProperty -name "streetAddress" -value (($userObject.streetAddress).ToString() -Replace "`r`n",", ") Add-Member -inputObject $user -type NoteProperty -name "l" -value ($userObject.l).ToString() Add-Member -inputObject $user -type NoteProperty -name "st" -value ($userObject.st).ToString() Add-Member -inputObject $user -type NoteProperty -name "postalCode" -value ($userObject.postalCode).ToString() Add-Member -inputObject $user -type NoteProperty -name "c" -value ($userObject.c).ToString() Add-Member -inputObject $user -type NoteProperty -name "telephoneNumber" -value ($userObject.telephoneNumber).ToString() Add-Member -inputObject $user -type NoteProperty -name "accountExpiration" -value $account_expiration Add-Member -inputObject $user -type NoteProperty -name "enabled" -value (Read-UserStatus $userObject.userAccountControl[0]) Add-Member -inputObject $user -type NoteProperty -name "organizationalUnit" -value ($userObject.psBase.parent.distinguishedName).ToString() $users += $user } } $users | Export-Csv -path $outputFile -noTypeInformation $users | ConvertTo-Html -property givenName,sn,mail,telephoneNumber,title,department -title "Important Contacts" > "contacts.html"
No comments:
Post a Comment