![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Read "userAccountControl" property to determine if account isdisabled? I have a PS script that retrieves an object's LastLogonTimeStamp and it's working fine (thanks to some VBS code from the MS ScriptCenter and a post by Shay in a previous thread on calling the VBS code from inside a PS function). I'd like to also check the status of the account and add some indicator in the output if the account is disabled. From some basic Google-fu, I've found that the disabled flag is stored in the second bit of the userAccountControl property. I've found plenty of examples how to add a binary "and" to the LDAP query string to return a list of enabled/disabled accounts, but I can't find anything on how to programmatically read the second bit directly once a user object has been obtained. My script takes a list of names, loops through them and uses the DirectorySearcher to retrieve the object with this query: (&(objectCategory=User)(sAMAccountName=$name)) I then use the FindOne() method of the DirectorySearcher to get the specific object. Once I have the object is there a way to just read the second bit of the userAccountControl property or do I need to execute another search and add that filter to the query? Something like this: (&(objectCategory=User)(sAMAccountName=$name)(userAccountControl: 1.2.840.113556.1.4.803:=2)) If that query returns a result then the account is disabled, but it seems like a second AD query is a waste of time if that attribute can be read directly. The script is below, if it helps to see it in context. I removed the "DisplayUsage" function from the listing to save space so ignore the call to it. Thanks, Paul param ( [string[]] $names, [string] $inputFile ) function Get-LastLogonTimeStamp($ldapPath) { $vbsCode = @" On Error Resume Next Set objUser = getObject(`"$ldapPath`") Set objLastLogon = objUser.Get("lastLogonTimeStamp") intLastLogonTime = objLastLogon.HighPart * (2^32) + objLastLogon.LowPart intLastLogonTime = intLastLogonTime / (60 * 10000000) intLastLogonTime = intLastLogonTime / 1440 result = intLastLogonTime + `#1/1/1601`# "@ $vbs = new-object -com MSScriptControl.ScriptControl $vbs.language = 'vbscript' $vbs.ExecuteStatement($vbsCode) $lastLogonTimeStamp = $vbs.Eval("result") if ($lastLogonTimeStamp -eq "1/1/1601 12:00:00 AM") { "Never" } else { $lastLogonTimeStamp } } if ($args -or (!$names -and !$inputFile)) { DisplayUsage exit } if ($inputFile) { $names += get-content $inputFile } if ($names) { $results = @{} $objSearcher = New-Object System.DirectoryServices.DirectorySearcher foreach ($name in $names) { $blnUser = $true $strFilter = "(&(objectCategory=User)(sAMAccountName=$name))" $objSearcher.Filter = $strFilter $objSearchResult = $objSearcher.FindOne() if (!$objSearchResult) { $blnUser = $false $strFilter = "(&(objectCategory=Computer)(Name=$name))" $objSearcher.Filter = $strFilter $objSearchResult = $objSearcher.FindOne() if (!$objSearchResult) { $displayName = $name.ToUpper() if (!$results.ContainsKey($displayName)) { $results += @{$displayName = "Object Not Found"} } } } if ($objSearchResult) { $object = $objSearchResult.GetDirectoryEntry() if ($blnUser) { $displayName = ([string]$object.sAMAccountName).ToUpper() } else { $displayName = ([string]$object.Name).ToUpper() } $lastLogon = Get-LastLogonTimeStamp($objSearchResult.Path) if (!$results.ContainsKey($displayName)) { $results += @{$displayName = $lastlogon} } } } } if ($results) { $results.GetEnumerator() } |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Read "userAccountControl" property to determine if account is disabled? <psmith2112@xxxxxx> wrote in message news:05c46ff3-6535-42d3-8c9b-738b4b0d8276@xxxxxx Quote: >I have a PS script that retrieves an object's LastLogonTimeStamp and > it's working fine (thanks to some VBS code from the MS ScriptCenter > and a post by Shay in a previous thread on calling the VBS code from > inside a PS function). > > I'd like to also check the status of the account and add some > indicator in the output if the account is disabled. From some basic > Google-fu, I've found that the disabled flag is stored in the second > bit of the userAccountControl property. disabled } else { enabled } |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Read "userAccountControl" property to determine if account is disabled? A couple of things... * This would be WAY eaiser using the FREE CMDlets from Quest http://www.quest.com/activeroles-server/arms.aspx * I would use DirectorySearcher for the LastLogonTimeStamp look here for more info http://bsonposh.com/modules/wordpress/?p=30 * There is a hidden GetEx() method you can use to get 'AccountDisabled'. Returns $true or $false Example: $user.psbase.invokeget('AccountDisabled') Brandon Shell --------------- Blog: http://www.bsonposh.com/ PSH Scripts Project: www.codeplex.com/psobject Quote: > I have a PS script that retrieves an object's LastLogonTimeStamp and > it's working fine (thanks to some VBS code from the MS ScriptCenter > and a post by Shay in a previous thread on calling the VBS code from > inside a PS function). > > I'd like to also check the status of the account and add some > indicator in the output if the account is disabled. From some basic > Google-fu, I've found that the disabled flag is stored in the second > bit of the userAccountControl property. I've found plenty of examples > how to add a binary "and" to the LDAP query string to return a list of > enabled/disabled accounts, but I can't find anything on how to > programmatically read the second bit directly once a user object has > been obtained. > > My script takes a list of names, loops through them and uses the > DirectorySearcher to retrieve the object with this query: > (&(objectCategory=User)(sAMAccountName=$name)) > > I then use the FindOne() method of the DirectorySearcher to get the > specific object. Once I have the object is there a way to just read > the second bit of the userAccountControl property or do I need to > execute another search and add that filter to the query? Something > like this: > (&(objectCategory=User)(sAMAccountName=$name)(userAccountControl: > 1.2.840.113556.1.4.803:=2)) > > If that query returns a result then the account is disabled, but it > seems like a second AD query is a waste of time if that attribute can > be read directly. > > The script is below, if it helps to see it in context. I removed the > "DisplayUsage" function from the listing to save space so ignore the > call to it. > > Thanks, > Paul > param ( > [string[]] $names, > [string] $inputFile > ) > function Get-LastLogonTimeStamp($ldapPath) { > $vbsCode = @" > On Error Resume Next > Set objUser = getObject(`"$ldapPath`") > Set objLastLogon = objUser.Get("lastLogonTimeStamp") > intLastLogonTime = objLastLogon.HighPart * (2^32) + > objLastLogon.LowPart > intLastLogonTime = intLastLogonTime / (60 * 10000000) > intLastLogonTime = intLastLogonTime / 1440 > result = intLastLogonTime + `#1/1/1601`# > "@ > $vbs = new-object -com MSScriptControl.ScriptControl > $vbs.language = 'vbscript' > $vbs.ExecuteStatement($vbsCode) > $lastLogonTimeStamp = $vbs.Eval("result") > if ($lastLogonTimeStamp -eq "1/1/1601 12:00:00 AM") { > "Never" > } > else { > $lastLogonTimeStamp > } > } > if ($args -or (!$names -and !$inputFile)) { > DisplayUsage > exit > } > if ($inputFile) { > $names += get-content $inputFile > } > if ($names) { > $results = @{} > $objSearcher = New-Object System.DirectoryServices.DirectorySearcher > foreach ($name in $names) { > $blnUser = $true > $strFilter = "(&(objectCategory=User)(sAMAccountName=$name))" > $objSearcher.Filter = $strFilter > $objSearchResult = $objSearcher.FindOne() > if (!$objSearchResult) { > $blnUser = $false > $strFilter = "(&(objectCategory=Computer)(Name=$name))" > $objSearcher.Filter = $strFilter > $objSearchResult = $objSearcher.FindOne() > if (!$objSearchResult) { > $displayName = $name.ToUpper() > if (!$results.ContainsKey($displayName)) { > $results += @{$displayName = "Object Not Found"} > } > } > } > if ($objSearchResult) { > $object = $objSearchResult.GetDirectoryEntry() > if ($blnUser) { > $displayName = ([string]$object.sAMAccountName).ToUpper() > } > else { > $displayName = ([string]$object.Name).ToUpper() > } > $lastLogon = Get-LastLogonTimeStamp($objSearchResult.Path) > if (!$results.ContainsKey($displayName)) { > $results += @{$displayName = $lastlogon} > } > } > } > } > if ($results) { > $results.GetEnumerator() > } |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Read "userAccountControl" property to determine if account isdisabled? On Dec 21, 11:29*am, Brandon Shell [MVP] <a_bshell.m...@xxxxxx> wrote: Quote: > A couple of things... > > * This would be WAY eaiser using the FREE CMDlets from Quest > * *http://www.quest.com/activeroles-server/arms.aspx > * I would use DirectorySearcher for the LastLogonTimeStamp look here for > more info > * *http://bsonposh.com/modules/wordpress/?p=30 > * There is a hidden GetEx() method you can use to get 'AccountDisabled'. > Returns $true or $false > * *Example: $user.psbase.invokeget('AccountDisabled') > > Brandon Shell > --------------- > Blog:http://www.bsonposh.com/ > PSH Scripts Project: *www.codeplex.com/psobject > as an exercise to get to know the DirectoryServices class a little better, before it morphed into something I thought would actually be useful. Then it became one of those "I know I can do this" things. ![]() The hidden GetEx() method works like a charm. Obviously I don't see it in the get-member list for a DirectoryEntry object. How would I go about finding hidden methods? Also, thanks to Bob for his -band solution. It looks like that also works, although I got a type convesion error when trying to use the userAccountControl attribute directly: PS C:\> $object.useraccountcontrol -band 2 Cannot convert "System.DirectoryServices.PropertyValueCollection" to "System.Int32". At line:1 char:33 + $object.useraccountcontrol -band <<<< 2 I noticed if I converted it to a string first, the type conversion would work: PS C:\> $object.useraccountcontrol.tostring() -band 2 0 Thanks for both solutions. Binary arithmetic is still a bit over my head. ![]() Thanks, Paul |
My System Specs![]() |
| | #5 (permalink) |
| | Re: Read "userAccountControl" property to determine if account is disabled? I don't know of an authorative list of these "hidden" methods\properties. I just know them from past experience. Brandon Shell --------------- Blog: http://www.bsonposh.com/ PSH Scripts Project: www.codeplex.com/psobject Quote: > On Dec 21, 11:29 am, Brandon Shell [MVP] <a_bshell.m...@xxxxxx> > wrote: > Quote: >> A couple of things... >> >> * This would be WAY eaiser using the FREE CMDlets from Quest >> http://www.quest.com/activeroles-server/arms.aspx >> * I would use DirectorySearcher for the LastLogonTimeStamp look here >> for >> more info >> http://bsonposh.com/modules/wordpress/?p=30 >> * There is a hidden GetEx() method you can use to get >> 'AccountDisabled'. >> Returns $true or $false >> Example: $user.psbase.invokeget('AccountDisabled') >> Brandon Shell >> --------------- >> Blog:http://www.bsonposh.com/ >> PSH Scripts Project: www.codeplex.com/psobject > as an exercise to get to know the DirectoryServices class a little > better, before it morphed into something I thought would actually be > useful. Then it became one of those "I know I can do this" > things. ![]() > The hidden GetEx() method works like a charm. Obviously I don't see > it in the get-member list for a DirectoryEntry object. How would I go > about finding hidden methods? > > Also, thanks to Bob for his -band solution. It looks like that also > works, although I got a type convesion error when trying to use the > userAccountControl attribute directly: > > PS C:\> $object.useraccountcontrol -band 2 > Cannot convert "System.DirectoryServices.PropertyValueCollection" to > "System.Int32". > At line:1 char:33 > + $object.useraccountcontrol -band <<<< 2 > I noticed if I converted it to a string first, the type conversion > would work: > > PS C:\> $object.useraccountcontrol.tostring() -band 2 0 > > Thanks for both solutions. Binary arithmetic is still a bit over my > head. ![]() > > Thanks, > Paul |
My System Specs![]() |
| | #6 (permalink) |
| | Re: Read "userAccountControl" property to determine if account is disabled? <psmith2112@xxxxxx> wrote in message news:1782989f-6e27-4efe-aa12-cd79b76ba9e4@xxxxxx On Dec 21, 11:29 am, Brandon Shell [MVP] <a_bshell.m...@xxxxxx> wrote: Quote: >PS C:\> $object.useraccountcontrol -band 2 > Cannot convert "System.DirectoryServices.PropertyValueCollection" to >"System.Int32". $object.userAccountControl.Value -band 2 |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| programmingly determine if "Show common tasks in folders" is selec | VB Script | |||
| How to: Dual use USB drive ---> Read/Write from Computer and Read from "Stand Alone DVD Player" | Vista General | |||
| How to determine "activations" left? (Vista Ultimate) | Vista General | |||
| How do you remove "Find a message" & "Add a newsgroup account" from the view? | Live Mail | |||
| "Setup cannot determine if this computer supprts installation." | Vista installation & setup | |||