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