I often need to retrieve data from Active Directory in many iterations which is very demanding and consumes all the RAM. Processing gradually slows down as well. Off course, a reduced amount of data could help (http://dmitrysotnikov.wordpress.com/2007/07/24/optimize-powershell-performance-and-memory-consumption/). But sometimes it could be better to use a multi-dimensional hash table to temporarily store data from AD rather than reading the data in each iteration. Reading data from a local variable is more effective.
How to add a few attributes to our hash table called ‚ADUsersCache‘ in example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
$SearchRoot = "OU=Users,DC=Domain,DC=Local" $SizeLimit = "0" $ADUsersCache=@{} if ( (Get-PSSnapin -Name quest.activeroles.admanagement -ErrorAction SilentlyContinue) -eq $Null ){ Add-PsSnapin quest.activeroles.admanagement } $ADUsers = Get-QADUser -SearchRoot $SearchRoot -SizeLimit $SizeLimit -DontUseDefaultIncludedProperties ` -IncludedProperties Name, LogonName, LogonScript, PrimarySMTPAddress, Title, Department foreach ($ADUser in $ADUsers) { $Name = $ADuser.Name $LogonName = $ADuser.LogonName $LogonScript = $ADuser.LogonScript $PrimarySMTPAddress = $ADuser.PrimarySMTPAddress $Title = $ADuser.Title $ADUsersCache += @{ "$LogonName" = @{ "Name"="$Name"; "LogonScript"="$LogonScript"; "PrimarySMTPAddress"="$PrimarySmtpAddress"; "Title"="$Title" "Department"="$Department" } } } |
Than i can work with…
1 2 |
$MyProperty = $ADUsersCache.GetEnumerator() | Where-Object {$_.Value.Title -ilike "*sales*"} $MyProperty.Key |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
Option Explicit Public Function SearchDistinguishedName(ByVal logonName, ByVal ADType, ByVal searchBy) Dim oRootDSE, oConnection, oCommand, oRecordSet Set oRootDSE = GetObject("LDAP://rootDSE") Set oConnection = CreateObject("ADODB.Connection") oConnection.Open "Provider=ADsDSOObject;" Set oCommand = CreateObject("ADODB.Command") oCommand.ActiveConnection = oConnection oCommand.CommandText = "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;(&(objectCategory=" & ADType &")(" & searchBy &"=" & LogonName & "));distinguishedName;subtree" Set oRecordSet = oCommand.Execute SearchDistinguishedName = oRecordSet.Fields("DistinguishedName") oConnection.Close Set oRecordSet = Nothing Set oCommand = Nothing Set oConnection = Nothing Set oRootDSE = Nothing End Function Public Function AddUserToADGroup(byval User, byval Group, byref Result) on error resume next dim strDNSDomain, objRootLDAP, foundUser, foundGroup, objUser, objGroup foundUser = SearchDistinguishedName(User, "User", "samAccountName") foundGroup = SearchDistinguishedName(Group, "Group", "Name") if IsEmpty(foundUser) then Result = "Chyba: Neexistujici uzivatel" elseif IsEmpty(foundGroup) then Result = "Chyba: Neexistujici skupina" end if if Result = "" then Set objRootLDAP = GetObject("LDAP://RootDSE") strDNSDomain = objRootLDAP.Get("DefaultNamingContext") Set objUser = GetObject("LDAP://"& foundUser) Set objGroup = GetObject("LDAP://"& foundGroup) objGroup.add(objUser.ADsPath) if Err.Number > 0 then Result = "Chyba: " & Err.Number & " " & Err.Description Err.Clear AddUserToADGroup = false else Result = nothing AddUserToADGroup = true End If end if if Result = "" then Result = "OK" end if End Function Dim Error AddUserToADGroup "strachotao", "Domain Admins", Error MsgBox Error |
Convert a NT system time (Integer8), in (10^-7)s intervals from 0h 1-Jan 1601, into a readable format. (pwdLastSet, lastLogon, etc)
w32tm /ntte %time%
Convert an NTP time, in (2^-32)s intervals from 0h 1-Jan 1900, into a readable format. (whenChanged, etc)
w32tm /ntpte %time%
Convert a datetime value to a NT system time (Opposite)
http://www.petri.co.il/software/datetointeger8.zip