Home All Groups Group Topic Archive Search About

Using WMI to disable a user account



Author
12 Apr 2007 8:36 PM
Paul
Hi,

I want to use a WMI script to disable a user account. Here's the test code
I'm using:

compName = "localhost"
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"& _
          compName & "\root\cimv2")
Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount")
For Each user In users
    If user.Name = "whatever" Then
        user.Disabled = True
    End If
Next 'user

The code runs fine (on a Windows Server 2003 box; I'm logged in as
Administrator), but the user's account is not disabled. Any idea why?

Thanks.
Paul

Author
13 Apr 2007 12:04 AM
Al Dunbar
Show quote
"Paul" <m***@DeleteThisPartmcfedries.com> wrote in message
news:B71B475B-AA52-414B-9E70-30407277BCD5@microsoft.com...
> Hi,
>
> I want to use a WMI script to disable a user account. Here's the test code
> I'm using:
>
> compName = "localhost"
> Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"& _
>          compName & "\root\cimv2")
> Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount")
> For Each user In users
>    If user.Name = "whatever" Then
>        user.Disabled = True
>    End If
> Next 'user
>
> The code runs fine (on a Windows Server 2003 box; I'm logged in as
> Administrator), but the user's account is not disabled. Any idea why?

Interesting. I had the same result on XP with a non-admin account, so it's
not just that you are testing against a name where the (upper/lower) case
doesn't match. I added some echo statements to make sure the .disabled
attribute has a boolean value and is modifiable, i.e.:

        compName = "localhost"
        Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"&
_
                 compName & "\root\cimv2")
        Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount")
        For Each user In users
           If user.Name = "zzz" Then
    wscript.echo "disabling user [" & user.name & "]"
    wscript.echo "[" & user.disabled & "]"
               user.Disabled = not user.disabled
    wscript.echo "[" & user.disabled & "]"
           End If
        Next 'user
    wscript.echo "after FOR EACH loop"

Since this indicated that the attribute had indeed changed (although not on
the actual account), it seems to me that there might perhaps be some
requirement to write the property back to the sam database with something
like the ".SetInfo" method used in active directory. There might be, but it
isn't user.setinfo, as that threw an "object doesn't support this property
or method" exception.

Curious.

/Al
Author
13 Apr 2007 4:24 AM
Richard Mueller [MVP]
Show quote
"Al Dunbar" <AlanD***@hotmail.com.nospaam> wrote in message
news:OW6hc9VfHHA.3648@TK2MSFTNGP05.phx.gbl...
>
> "Paul" <m***@DeleteThisPartmcfedries.com> wrote in message
> news:B71B475B-AA52-414B-9E70-30407277BCD5@microsoft.com...
>> Hi,
>>
>> I want to use a WMI script to disable a user account. Here's the test
>> code I'm using:
>>
>> compName = "localhost"
>> Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"& _
>>          compName & "\root\cimv2")
>> Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount")
>> For Each user In users
>>    If user.Name = "whatever" Then
>>        user.Disabled = True
>>    End If
>> Next 'user
>>
>> The code runs fine (on a Windows Server 2003 box; I'm logged in as
>> Administrator), but the user's account is not disabled. Any idea why?
>
> Interesting. I had the same result on XP with a non-admin account, so it's
> not just that you are testing against a name where the (upper/lower) case
> doesn't match. I added some echo statements to make sure the .disabled
> attribute has a boolean value and is modifiable, i.e.:
>
>        compName = "localhost"
>        Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"&
> _
>                 compName & "\root\cimv2")
>        Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount")
>        For Each user In users
>           If user.Name = "zzz" Then
>    wscript.echo "disabling user [" & user.name & "]"
>    wscript.echo "[" & user.disabled & "]"
>               user.Disabled = not user.disabled
>    wscript.echo "[" & user.disabled & "]"
>           End If
>        Next 'user
>    wscript.echo "after FOR EACH loop"
>
> Since this indicated that the attribute had indeed changed (although not
> on the actual account), it seems to me that there might perhaps be some
> requirement to write the property back to the sam database with something
> like the ".SetInfo" method used in active directory. There might be, but
> it isn't user.setinfo, as that threw an "object doesn't support this
> property or method" exception.
>
> Curious.
>
> /Al
>
>

Documentation says that the Disabled property is read/write. Also says that
if a property is read-only, no error is raised when you attempt to modify
the value. This acts as if the property is read-only. Strange.

It doesn't help this problem, but the query would be more efficient if you
specified the user. For example:

Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount WHERE Name =
'MyUserName'")

or another option could be:

Set objUser = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer _
    & "\root\cimv2:Win32_UserAccount." _
    & "Domain='MyDomain',Name='MyUserName'")

--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
--
Author
13 Apr 2007 9:59 AM
Paul
"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.nospam.net> wrote in
message news:u%23vg6QYfHHA.4156@TK2MSFTNGP02.phx.gbl...
> Documentation says that the Disabled property is read/write. Also says
> that if a property is read-only, no error is raised when you attempt to
> modify the value. This acts as if the property is read-only. Strange.

Actually, the property *does* change, albeit briefly. Consider the following
variation:

compName = "localhost"
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//"& compName
& "\root\cimv2")
Set users = wmi.ExecQuery("SELECT * FROM Win32_UserAccount WHERE
Description='whatever'")

For Each user In users
    user.Disabled = True
    WScript.Echo user.Name & ": " & user.Disabled
Next 'user

For Each user In users
    WScript.Echo user.Name & ": " & user.Disabled
Next 'user

In the first Echo, Disabled returns True; in the second Echo, it returns
False!

I wonder if it's similar to making changes in an ADO Recordset, where after
you edit a field value you have to run the Update method to write the
changes. Might there be some WMI equivalent to the ADO Update method?

Paul

AddThis Social Bookmark Button