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
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
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
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?
Can you try passing the NonInteractive parameter on the powershell command ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
$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
|
|
-----------------------------------------------------------------------------------------------------------------------
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
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.
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
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:
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
Which OS are you running in your guest ?
I tested against a W2K8R2.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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.
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
This post might explain what is happening.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
|
|
-----------------------------------------------------------------------------------------------------------------------
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?
How did you specify the guest account ?
As "domain\user" or as "user@domain" ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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.
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
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.