WMI Privilege Problem on Reboot call 
Author Message
 WMI Privilege Problem on Reboot call

I am writing a simple class whose only job is to reboot a specified server
using the System.Management namespace and WMI.  My code is below.  I am
currently calling this class from a simple windows form, but eventually I
would like to call it from a web form.

The code below will work when a remote machine is specified, but every time
I try to run it locally I get a "Privilege Not Held" error.  I am running
the code on a Win2k server while logged in as the local administrator on the
machine.  I have verified that the user has "Shut Down The System"
privileges set in the policy.  When I try to connect to WMI locally, I
cannot specify a username and password.  I can only assume that the app is
connecting on behalf of the currently logged in user.  Is this a valid
assumption?

Can anyone tell me how I can get this code to work on a local server?
Thanks.

Jamie Gaines

----------------------------------------------------------------------------
-------
Imports System
Imports System.Management

Public Class WMIWrapper

Private Sub New()
    End Sub

    Public Shared Sub Reboot(ByVal server As String, ByVal username As
String, ByVal password As String)

        Dim Path As New ManagementPath()
        Path.Server = server
        Path.NamespacePath = "root\CIMV2"

        Dim Scope As New ManagementScope(Path)

        If UCase(server) <> UCase(System.Environment.MachineName) Then
            Scope.Options.Username = username
            Scope.Options.Password = password
        End If

        Scope.Options.Impersonation = ImpersonationLevel.Impersonate
        Scope.Options.EnablePrivileges = True
        Scope.Connect()

        Dim Query As New ObjectQuery("SELECT * FROM Win32_OperatingSystem
where primary=true")
        Dim Searcher As New ManagementObjectSearcher(Scope, Query)
        Dim MyObjects As ManagementObjectCollection
        Dim myObject As New ManagementObject()
        Dim InParams As ManagementBaseObject()

        MyObjects = Searcher.Get

        For Each myObject In MyObjects
            Scope.Options.EnablePrivileges = True
            myObject.InvokeMethod("Reboot", InParams)
        Next

    End Sub

End Class



Sun, 12 Dec 2004 19:28:04 GMT  
 WMI Privilege Problem on Reboot call
You need to enable the privileges for the object your are binding to.
...
        For Each myObject In MyObjects
            myObject .Scope.Options.EnablePrivileges = True
...

The other Scope objects are not required.

Willy.

Quote:

> I am writing a simple class whose only job is to reboot a specified server
> using the System.Management namespace and WMI.  My code is below.  I am
> currently calling this class from a simple windows form, but eventually I
> would like to call it from a web form.

> The code below will work when a remote machine is specified, but every time
> I try to run it locally I get a "Privilege Not Held" error.  I am running
> the code on a Win2k server while logged in as the local administrator on the
> machine.  I have verified that the user has "Shut Down The System"
> privileges set in the policy.  When I try to connect to WMI locally, I
> cannot specify a username and password.  I can only assume that the app is
> connecting on behalf of the currently logged in user.  Is this a valid
> assumption?

> Can anyone tell me how I can get this code to work on a local server?
> Thanks.

> Jamie Gaines

> ----------------------------------------------------------------------------
> -------
> Imports System
> Imports System.Management

> Public Class WMIWrapper

> Private Sub New()
>     End Sub

>     Public Shared Sub Reboot(ByVal server As String, ByVal username As
> String, ByVal password As String)

>         Dim Path As New ManagementPath()
>         Path.Server = server
>         Path.NamespacePath = "root\CIMV2"

>         Dim Scope As New ManagementScope(Path)

>         If UCase(server) <> UCase(System.Environment.MachineName) Then
>             Scope.Options.Username = username
>             Scope.Options.Password = password
>         End If

>         Scope.Options.Impersonation = ImpersonationLevel.Impersonate
>         Scope.Options.EnablePrivileges = True
>         Scope.Connect()

>         Dim Query As New ObjectQuery("SELECT * FROM Win32_OperatingSystem
> where primary=true")
>         Dim Searcher As New ManagementObjectSearcher(Scope, Query)
>         Dim MyObjects As ManagementObjectCollection
>         Dim myObject As New ManagementObject()
>         Dim InParams As ManagementBaseObject()

>         MyObjects = Searcher.Get

>         For Each myObject In MyObjects
>             Scope.Options.EnablePrivileges = True
>             myObject.InvokeMethod("Reboot", InParams)
>         Next

>     End Sub

> End Class



Sun, 12 Dec 2004 20:28:53 GMT  
 WMI Privilege Problem on Reboot call
Willy:

Thank you for replying to my post.  I changed the code as you suggested, yet
I am still getting the same "Privilege Not Held" error when I call the
InvokeMethod procedure.  I have read many of your other posts concerning
this topic and have tried everything you and others have suggested, yet I
cannot get this code to work locally.  Here are the things I have done.

I am running the application as a user in the local Administrators group.  I
have confirmed this by checking the username of the process in the Task
Manager.

The local Administrators group is listed in the "Shut down the system"
policy under the Local Policies / User Rights Assignment node of the Local
Security Settings application.

I even used the .NET Framework configuration utility to give my assembly
Full Rights, thinking this might be the problem.

I am testing this application with a laptop and a desktop.  If I run the
application from the laptop, specify the desktop as the target machine, and
supply local admin credentials for the desktop, the desktop will restart.
If I run the exact same application locally on the desktop, while logged in
as the same user I specifed when running the application from the laptop, it
fails with the "Privilege Not Held" error.

I can only assume from this result that when I am running the application
locally, it is somehow not accessing WMI as the user I am logged in as, even
though I have verifed the username on the process in the Task Manager.  Do
you think this might be correct?  Is there something else that I should try
from a permissions standpoint?  Am I crazy?   :^)

Thanks for any additional insight you or anyone else might provide.

Kind Regards,
Jamie Gaines



Quote:
> You need to enable the privileges for the object your are binding to.
> ...
>         For Each myObject In MyObjects
>             myObject .Scope.Options.EnablePrivileges = True
> ...

> The other Scope objects are not required.

> Willy.




Quote:
> > I am writing a simple class whose only job is to reboot a specified
server
> > using the System.Management namespace and WMI.  My code is below.  I am
> > currently calling this class from a simple windows form, but eventually
I
> > would like to call it from a web form.

> > The code below will work when a remote machine is specified, but every
time
> > I try to run it locally I get a "Privilege Not Held" error.  I am
running
> > the code on a Win2k server while logged in as the local administrator on
the
> > machine.  I have verified that the user has "Shut Down The System"
> > privileges set in the policy.  When I try to connect to WMI locally, I
> > cannot specify a username and password.  I can only assume that the app
is
> > connecting on behalf of the currently logged in user.  Is this a valid
> > assumption?

> > Can anyone tell me how I can get this code to work on a local server?
> > Thanks.

> > Jamie Gaines

> --------------------------------------------------------------------------
--
> > -------
> > Imports System
> > Imports System.Management

> > Public Class WMIWrapper

> > Private Sub New()
> >     End Sub

> >     Public Shared Sub Reboot(ByVal server As String, ByVal username As
> > String, ByVal password As String)

> >         Dim Path As New ManagementPath()
> >         Path.Server = server
> >         Path.NamespacePath = "root\CIMV2"

> >         Dim Scope As New ManagementScope(Path)

> >         If UCase(server) <> UCase(System.Environment.MachineName) Then
> >             Scope.Options.Username = username
> >             Scope.Options.Password = password
> >         End If

> >         Scope.Options.Impersonation = ImpersonationLevel.Impersonate
> >         Scope.Options.EnablePrivileges = True
> >         Scope.Connect()

> >         Dim Query As New ObjectQuery("SELECT * FROM

Win32_OperatingSystem

- Show quoted text -

Quote:
> > where primary=true")
> >         Dim Searcher As New ManagementObjectSearcher(Scope, Query)
> >         Dim MyObjects As ManagementObjectCollection
> >         Dim myObject As New ManagementObject()
> >         Dim InParams As ManagementBaseObject()

> >         MyObjects = Searcher.Get

> >         For Each myObject In MyObjects
> >             Scope.Options.EnablePrivileges = True
> >             myObject.InvokeMethod("Reboot", InParams)
> >         Next

> >     End Sub

> > End Class



Sun, 12 Dec 2004 21:36:08 GMT  
 WMI Privilege Problem on Reboot call
Compile this C# program from the commandline and try:

using System;
using System.Management;
using System.Runtime.InteropServices;
public class Wmis {
 public static void Main() {
  Reboot();
 }
 public static void  Reboot( )
  {
   try
   {
    SelectQuery query = new SelectQuery("select name from Win32_OperatingSystem where primary=true");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    foreach(ManagementObject os in searcher.Get())
    {
     // Enable SeShutdownPrivilege, the calling process must have SeShutdownPrivilege
     os.Scope.Options.EnablePrivileges = true;
     ManagementBaseObject outParams = os.InvokeMethod("Reboot", null, null);
    }
   }
   catch (Exception e)
   {
    Console.WriteLine(e.ToString());
   }
  }

Willy.



Sun, 12 Dec 2004 23:03:50 GMT  
 WMI Privilege Problem on Reboot call
Willy:

Thanks again for taking the time to follow up on this with me.  This just
gets stranger and stranger.

First of all, your code runs like a champ on both of my machines.  If I port
it into a VB.net console app, I get the same error "Privilege not held"
error.  Here's my port.

Imports System
Imports System.Management
Imports System.Runtime.InteropServices

Public Class Module1
    Shared Sub Main()
        Reboot()
    End Sub

    Public Shared Sub Reboot()

        Try
            Dim Query As New ObjectQuery("SELECT name FROM
Win32_OperatingSystem where primary=true")
            Dim Searcher As New ManagementObjectSearcher(Query)
            Dim myObject As New ManagementObject()
            Dim outParams As ManagementBaseObject

            For Each myObject In Searcher.Get
                myObject.Scope.Options.EnablePrivileges = True
                outParams = myObject.InvokeMethod("Reboot", Nothing,
Nothing)
            Next

        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try

    End Sub

End Class

If I take your C# code and put the Reboot method into a static class that I
call from my test client, I get the privilege not held error as well.

Very weird.  Anyway, your code has at least pointed me in the right
direction.  It's not a requirement that the code be in VB, but I would like
to be able to wrap it in a class as opposed to having to call an external
console app.

Thanks again for all your help.  I'll post back if I find anything else.

JG



Quote:
> Compile this C# program from the commandline and try:

> using System;
> using System.Management;
> using System.Runtime.InteropServices;
> public class Wmis {
>  public static void Main() {
>   Reboot();
>  }
>  public static void  Reboot( )
>   {
>    try
>    {
>     SelectQuery query = new SelectQuery("select name from

Win32_OperatingSystem where primary=true");
Quote:
>     ManagementObjectSearcher searcher = new

ManagementObjectSearcher(query);
Quote:
>     foreach(ManagementObject os in searcher.Get())
>     {
>      // Enable SeShutdownPrivilege, the calling process must have
SeShutdownPrivilege
>      os.Scope.Options.EnablePrivileges = true;
>      ManagementBaseObject outParams = os.InvokeMethod("Reboot", null,
null);
>     }
>    }
>    catch (Exception e)
>    {
>     Console.WriteLine(e.ToString());
>    }
>   }

> Willy.




- Show quoted text -



Mon, 13 Dec 2004 02:35:06 GMT  
 WMI Privilege Problem on Reboot call
This looks like a bug.
When you change the C# sample and decorate the Main function with [STAThread], the same exception is being thrown, that means that
the identity of the caller changes when the Management/WMI code migrates to an MTA thread!!!.
The VB.Net compiler initializes the main thread to enter an STA by default, but all winforms applications must run their main thread
in a STA.
That means that , you need to start a worker thread in a MTA, and call the WMI stuff from this thread.

Willy.

Quote:

> Willy:

> Thanks again for taking the time to follow up on this with me.  This just
> gets stranger and stranger.

> First of all, your code runs like a champ on both of my machines.  If I port
> it into a VB.net console app, I get the same error "Privilege not held"
> error.  Here's my port.

> Imports System
> Imports System.Management
> Imports System.Runtime.InteropServices

> Public Class Module1
>     Shared Sub Main()
>         Reboot()
>     End Sub

>     Public Shared Sub Reboot()

>         Try
>             Dim Query As New ObjectQuery("SELECT name FROM
> Win32_OperatingSystem where primary=true")
>             Dim Searcher As New ManagementObjectSearcher(Query)
>             Dim myObject As New ManagementObject()
>             Dim outParams As ManagementBaseObject

>             For Each myObject In Searcher.Get
>                 myObject.Scope.Options.EnablePrivileges = True
>                 outParams = myObject.InvokeMethod("Reboot", Nothing,
> Nothing)
>             Next

>         Catch ex As Exception
>             Console.WriteLine(ex.Message)
>         End Try

>     End Sub

> End Class

> If I take your C# code and put the Reboot method into a static class that I
> call from my test client, I get the privilege not held error as well.

> Very weird.  Anyway, your code has at least pointed me in the right
> direction.  It's not a requirement that the code be in VB, but I would like
> to be able to wrap it in a class as opposed to having to call an external
> console app.

> Thanks again for all your help.  I'll post back if I find anything else.

> JG



> > Compile this C# program from the commandline and try:

> > using System;
> > using System.Management;
> > using System.Runtime.InteropServices;
> > public class Wmis {
> >  public static void Main() {
> >   Reboot();
> >  }
> >  public static void  Reboot( )
> >   {
> >    try
> >    {
> >     SelectQuery query = new SelectQuery("select name from
> Win32_OperatingSystem where primary=true");
> >     ManagementObjectSearcher searcher = new
> ManagementObjectSearcher(query);
> >     foreach(ManagementObject os in searcher.Get())
> >     {
> >      // Enable SeShutdownPrivilege, the calling process must have
> SeShutdownPrivilege
> >      os.Scope.Options.EnablePrivileges = true;
> >      ManagementBaseObject outParams = os.InvokeMethod("Reboot", null,
> null);
> >     }
> >    }
> >    catch (Exception e)
> >    {
> >     Console.WriteLine(e.ToString());
> >    }
> >   }

> > Willy.






Mon, 13 Dec 2004 05:29:54 GMT  
 WMI Privilege Problem on Reboot call
Here is a solution using async delegates and the threadpool, this requires very little code changes.

using System;
using System.Management;
using System.Runtime.InteropServices;
public class Wmis {
 [STAThread]
 public static void Main() {
  // Call Reboot() on an MTA thread from the thread pool using a delegate
  RebootProc pfn = new RebootProc(Reboot);
  pfn.BeginInvoke( null, null);
  Console.ReadLine(); // this is needed to block the main thread.
 }

 public delegate void RebootProc();
 static void  Reboot( )
  {
   try
   {
    SelectQuery query = new SelectQuery("select name from Win32_OperatingSystem where primary=true");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
    foreach(ManagementObject os in searcher.Get())
    {
     Console.WriteLine(os["Name"]);
     // Enable SeShutdownPrivilege, the calling process must have SeShutdownPrivilege
     os.Scope.Options.EnablePrivileges = true;
     ManagementBaseObject outParams = os.InvokeMethod("Reboot", null, null);
    }
   }
   catch (Exception e)
   {
    Console.WriteLine(e.ToString());
   }
  }

Quote:
}


Quote:
> This looks like a bug.
> When you change the C# sample and decorate the Main function with [STAThread], the same exception is being thrown, that means that
> the identity of the caller changes when the Management/WMI code migrates to an MTA thread!!!.
> The VB.Net compiler initializes the main thread to enter an STA by default, but all winforms applications must run their main
thread
> in a STA.
> That means that , you need to start a worker thread in a MTA, and call the WMI stuff from this thread.

> Willy.



Mon, 13 Dec 2004 05:43:35 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. WMI - WMI Login Cotrol causes exception when destroying

2. RegSaveKey privilege problem

3. SetLocalTime() privilege problem in NT

4. SetLocalTime() privilege problem under NT

5. WMI Win32_LoggedOnUser problem...

6. WMI Event/Schema & ASP.NET problem

7. Problem with Reboot

8. Problem calling into managed DLL that calls unmanaged DLL

9. Winword problem w/ a DeleteFile call after a Navigate call

10. NEWBIE calling ATL gods: Problem in calling DOM object

11. CMap call within function call problem

12. Execute command which requried root privileges.

 

 
Powered by phpBB® Forum Software