VMware Cloud Community
jl999
Contributor
Contributor

Invoke-VMScript to run ps commands as an administrator

Hello, I'd like to run the following command:

$cn = "myComputer"

$text = "(Get-WmiObject Win32_ComputerSystem).Rename($cn)"

$vm = Get-VM oldName

$vm | Invoke-VMScript -ScriptText $text -GuestCredential $myCred

The command ran successfully against the vm. But the WMI call return value is 5 (probably access denied of sort), instead of 0.

If I log onto the VM, and open a PS window as Administrator, then run:

(Get-Win32_ComputerSystem).Rename($cn)

It would be successful, and after rebooting the VM, the name of the vm is changed.

But I can't get this working using Invoke-VMScript. It doesn't seem there's a way to invoke the command in an elevated PS session.

Any help is apprieciated.

Jason

Tags (2)
Reply
0 Kudos
22 Replies
jdptechnc
Expert
Expert

There are some API calls that Windows prevents you from performing remotely. The rename method appears to be one of them.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa393056(v=vs.85).aspx

Please consider marking as "helpful", if you find this post useful. Thanks!... IT Guy since 12/2000... Virtual since 10/2006... VCAP-DCA #2222
Reply
0 Kudos
LucD
Leadership
Leadership

With the Invoke-VMScript cmdlet you don't run the script remotely, but inside the guest OS of the VM.

And there are methods to run a .ps1 script elevated. See for example Re-launch Powershell Script Elevated

The prequisite is of course that the account you use inside the guest OS, the GuestCredential, is member of the local Administrators group in the guest OS.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

So I tried this way:

$vm = Get-VM myVM

$scriptText = "Start-Process Powershell -Verb RunAs -Arg '-command `"Get-Process`"'"

$vm | Invoke-VMScript -ScriptText $scriptText -GuestCredential $myCred

This gives me an error:

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
Start-Process : This command cannot be executed due to the error: This operatio
|  n requires an interactive window station.
|  At line:1 char:17
|  + & {start-process <<<<  powershell -verb RunAs -Arg '-command "get-process"'}
|      + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOp
|     erationException
|      + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
|     ommands.StartProcessCommand
|
|
-----------------------------------------------------------------------------------------------------------------------

But if I try:

$scriptText = "Get-Process"

$vm | Invoke-VMScript -ScriptText $scriptText -GuestCredential $myCred

It runs successfully.

My question is: how do you run commands that's wrapped in Invoke-VMScript in a guest OS as an administrator?

Reply
0 Kudos
LucD
Leadership
Leadership

Can you try passing the NonInteractive parameter on the powershell command ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

$scriptText = "start-process powershell -verb RunAs -Arg '-noninteractive -command `"get-process`"'"

I got an error:

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
Start-Process : This command cannot be executed due to the error: This operatio
|  n requires an interactive window station.
|  At line:1 char:17
|  + & {start-process <<<<  powershell -verb RunAs -Arg '-noninteractive -command
|  "get-process"'}
|      + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOp
|     erationException
|      + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
|     ommands.StartProcessCommand
|
|
-----------------------------------------------------------------------------------------------------------------------

Tried this:

$scriptText = "start-process powershell -verb RunAs -Arg '-noninteractive', '-command `"get-process`"'"

And still no go:

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
Start-Process : This command cannot be executed due to the error: This operatio
|  n requires an interactive window station.
|  At line:1 char:17
|  + & {start-process <<<<  powershell -verb RunAs -Arg '-noninteractive', '-comma
|  nd "get-process"'}
|      + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOp
|     erationException
|      + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
|     ommands.StartProcessCommand
|
|
-----------------------------------------------------------------------------------------------------------------------

Reply
0 Kudos
LucD
Leadership
Leadership

When I provide the powershell command like this it seems to work (for me)

$cred = Get-Credential -Credential 'domain\user'

$scriptext
= "Start-Process powershell -Credential $cred -ArgumentList '-noprofile -noninteractive -command get-service'"

You can of course get the credential for the runas account in a different way, you could for example store this in a file.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

Hey Luc, thanks for the reply.

Did you try to use -Verb RunAs in your $scriptText?

I think it's a UAC issue at the guest OS level.

Here's what I tried:

console into the guest OS, open up a Powershell window, at the prompt:

Start-Process Powershell -Verb RunAs -Argumentlist '-NonInteractive -command Get-Service'

I still get a prompt (see the image below). Maybe there's some kind of settings in the OS that still requires me to hit the "Yes" button. That might explain why Invoke-VMScript complains that the operation requires an interactive window station.

Capture.PNG
Reply
0 Kudos
LucD
Leadership
Leadership

Indeed, the UAC is blocking your script on the target machine.

The following function comes from Jeff Wouter's post called Having some fun with UAC and PowerShell.

That seems to work for me.

$script = ' 
function
Elevate-Process  { param ([string]$exe = $(Throw "Pleave provide the name and path of an executable"),[string]$arguments) $startinfo = new-object System.Diagnostics.ProcessStartInfo
$startinfo.FileName = $exe
$startinfo.Arguments = $arguments
$startinfo.verb = "RunAs"
$process
= [System.Diagnostics.Process]::Start($startinfo) } Elevate-Process -Exe powershell.exe -Arguments "-noninteractive -command Get-Process > C:\test.txt"
'
Get-VM
MyVM | Invoke-VMScript -ScriptText $script -ScriptType PowerShell

Btw the Verb and the Credential parameter for the Start-Process cmdlet can't be used together, they belong to different parametersets.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

Hmm, maybe there are some issues with my VM. Somehow I still got the same old error message stating it requires a interactive window station.

I also tried to run the content of $script in the guest OS. And I got prompted with UAC dialog box again.

There's a way to disable UAC prompt:

http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/ee94d7d3-3d10-4095-a757-...

Set-ItemProperty -Path registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\policies\system -Name EnableLUA -Value 0

But to run that piece of code I need to get to the Powershell elevated prompt first Smiley Sad

Reply
0 Kudos
LucD
Leadership
Leadership

Which OS are you running in your guest ?

I tested against a W2K8R2.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

Mine's W2K8R2 Standard. It was a fresh build from a template that was given by our OS team. The task I was trying to accomplish was to change the server name, as the template was sys-prep'ed. The VM has no network connectivity and has not joined a domain yet. The only account on the OS is the local administrator.

Reply
0 Kudos
LucD
Leadership
Leadership

Are there any messages in the C:\test.txt file inside the guest ?

In my code I redirect the stdout to that file.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership

This post might explain what is happening.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jl999
Contributor
Contributor

Thanks again Luc for the info. I probably have to accept the fact that at this stage I cannot pass the UAC prompt without doing some heavy-duty coding on win32 api's -- am not familiar with win32 api's at all.

To answer your previous question regarding c:\test.txt file. No, the file wasn't created at guest OS. Running the script generated the same error:

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
Exception calling "Start" with "1" argument(s): "This operation requires an int
|  eractive window station"
|  At line:7 char:47
|  + $process = [System.Diagnostics.Process]::Start <<<< ($startinfo)
|      + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
|      + FullyQualifiedErrorId : DotNetMethodException
|
|
-----------------------------------------------------------------------------------------------------------------------

Reply
0 Kudos
Morten_Dalgaard
Enthusiast
Enthusiast

I'm also trying to make LucD's example work.

And it does actually run, when running exactly as written.

The issue that i'm having, is that this means running with your current credentials.

If the target machine is in another domain, you would need to append GuestCredentials to the Invoke-VMscript command.

However doing this, results in the same error:

|  Exception calling "Start" with "1" argument(s): "This operation requires an interactive window station"

Are there really no way to run scripts through Invoke-VMscript with elevated access, without disabling UAC?

Reply
0 Kudos
LucD
Leadership
Leadership

How did you specify the guest account ?

As "domain\user" or as "user@domain" ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Morten_Dalgaard
Enthusiast
Enthusiast

Heres the snip:

$secpasswd = ConvertTo-SecureString "password" -AsPlainText -Force

$mycreds = New-Object System.Management.Automation.PSCredential ("localuser", $secpasswd)

Get-VM vm | Invoke-VMScript -ScriptText $script -ScriptType PowerShell -GuestCredential $mycreds

I'm actually trying to run it as a local user in the Administrators group (but not an actually administrator because of UAC).

I've also tried specifying GuestUser/GuestPassword, but same error.

Reply
0 Kudos
LucD
Leadership
Leadership

In that case, did you also try as "hostname\localuser" or "localuser@hostname" ?

Replace the domain by the guest OS hostname of the VM.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Morten_Dalgaard
Enthusiast
Enthusiast

Yes, the problem does not seem to be with the credentials, as i can run any other script not requiring elevation just fine.

But when used with the elevation code you posted, it errors out when using GuestCredentials.

Reply
0 Kudos