Running commands in elevated prompt on remote computer

I’m trying to register a new SCOM Gateway server by executing the following commands on a SCOM Management server in an elevated ISE prompt:

$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
Set-Location "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup"  
.\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe /ManagementServerName=$ManagementServerFQDN /GatewayName=$NewSCOMGWComputerFQDN /Action=Create  

This works fine and I get output similar to:

Microsoft.EnterpriseManagement.GatewayApprovalTool
Copyright (c) Microsoft Corporation. All rights reserved.

The approval of server new123.abc.com completed successfully.

PS C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup> 

However, this GatewayApprovalTool.exe simply hangs when I try to run it remotely.
First attempt:

$myCred = Get-Credential -Username 'domain\user' # this is local admin on $ManagementServerFQDN
$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
Invoke-Command -ComputerName $ManagementServerFQDN -Credential $MyCred -ScriptBlock {
    Set-Location "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup"  
    .\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe /ManagementServerName=$Using:ManagementServerFQDN /GatewayName=$Using:NewSCOMGWComputerFQDN /Action=Create  
}

Second attempt:

$myCred = Get-Credential -Username 'domain\user' # this is local admin on $ManagementServerFQDN
$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
Invoke-Command -ComputerName $ManagementServerFQDN -Credential $MyCred -ScriptBlock {
    $ScriptPath = "$env:windir\temp1.ps1"
    'Set-Location "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup"' | Out-File $ScriptPath -Force
    ".\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe /ManagementServerName=$Using:ManagementServerName /GatewayName=$Using:NewSCOMGWComputerFQDN /Action=Create |" | Out-File $ScriptPath -Append
    # This works locally but not remotely :(
    Start-Process powershell.exe -Verb runas -ArgumentList "-File $ScriptPath -ExecutionPolicy Unrestricted -WindowStyle Hidden -NoProfile"
}

Third attempt:

$myCred = Get-Credential -Username 'domain\user' # this is local admin on $ManagementServerFQDN
$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
Invoke-Command -ComputerName $ManagementServerFQDN -Credential $MyCred -ScriptBlock {
    $ScriptPath = "$env:windir\temp1.ps1"
    $myCred = $Using:myCred
    Remove-Item "$env:windir\temp1.txt" -Force -EA 0 | Out-Null
    'Set-Location "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup"' | Out-File $ScriptPath -Force
    ".\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe /ManagementServerName=$Using:ManagementServerFQDN  /GatewayName=$Using:NewSCOMGWComputerFQDN /Action=Create |" | Out-File $ScriptPath -Append
    '    Out-File "$env:windir\temp1.txt" -Force' | Out-File $ScriptPath -Append
    $TaskName = 'RegisterSCOMGateway'
    $TaskRun = "powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NoLogo -NonInteractive -WindowStyle Hidden -Command ""$ScriptPath""" 
    $StartAt = "$((Get-Date).AddMinutes(1))"
    $StartAt = "$($StartAt.Split(' ')[1].Split(':')[0]):$($StartAt.Split(':')[1])"  
    SCHTASKS /Create /S $Env:COMPUTERNAME /RU $Using:MyCred.UserName /RP ($MyCred.GetNetworkCredential().Password) /TN $TaskName /TR $TaskRun /SC ONCE /ST $StartAt /RL HIGHEST /F  
    while (!(Test-Path "$env:windir\temp1.txt")) {
        Start-Sleep -Seconds 5
        Write-Host '.' -NoNewline
        }
    while (!((Get-Content "$env:windir\temp1.txt")[-1])) {
        Start-Sleep -Seconds 5
        Write-Host '.' -NoNewline
    }
    SCHTASKS /Delete /F /TN "\$TaskName"  
    Get-Content "$env:windir\temp1.txt"
}

You can see the task created and running but never finishing

Any suggestions on how to run exe remotely in elevated prompt?

You’re already running it under elevated privileges; it’s very likely that isn’t the problem. Remote sessions aren’t a “full” logon session - there’s no user profile, for example. It’s possible the executable just won’t run under the more constrained circumstances.

Try connecting to the computer by using Enter-PSSession, and then running the command. Does it behave any differently?

no difference :frowning:
It just sits there…

PS C:\Scripts\git> Enter-PSSession mxxxx01.mydomain.com -Credential (Get-SBCredential 'domain\admin')

[mxxxx01.mydomain.com]: PS C:\Users\admin\Documents> Set-Location "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup"  

[mxxxx01.mydomain.com]: PS C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup> .\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe /ManagementServerName=mxxxx01.mydomain.com /GatewayName=new123.abc.com /Action=Create  
Microsoft.EnterpriseManagement.GatewayApprovalTool
Copyright (c) Microsoft Corporation. All rights reserved.

Looking at the folder where the GatewayApprovalTool.exe is located, I see .config files and .dll files that suggest that this is a .net app. I’m not a developer but I imagine that instead of using the .exe, I can load the assemblies used by the .exe and invoke the needed function(s) to complete this task. Is that a plausible solution? Any suggestions on how to pursue it?

It’s probably not quite that straightforward, unless you know exactly what the EXE is calling. It’s very likely that the problem here is that the code expects a full user session to exist, which is impossible via Remoting. I don’t think it has anything to do with credentials or privilege. You could potentially look at SSH or something, which is a true interactive logon session in most cases, as an alternative.

And Russinovich strikes again :slight_smile:
I found a work around using PSExec:

$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
$MyCred = Get-SBCredential -UserName 'domain\admin'
..\PSTools\PsExec.exe -accepteula
..\PSTools\PsExec.exe \\$ManagementServerFQDN -u $MyCred.UserName -p $MyCred.GetNetworkCredential().Password -h "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe" /ManagementServerName=$ManagementServerFQDN /GatewayName=$NewSCOMGWComputerFQDN /Action=Create 

and it works!!

PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

Microsoft.EnterpriseManagement.GatewayApprovalTool
Copyright (c) Microsoft Corporation. All rights reserved.

The approval of server new123.abc.com completed successfully.
..\PSTools\PsExec.exe : Connecting to mxxxx01.mydomain.com...
At line:1 char:1
+ ..\PSTools\PsExec.exe \\$ManagementServerFQDN -u $MyCred.UserName -p  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Connecting to mxxxx01.mydomain.com...:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
Starting PSEXESVC service on mxxxx01.mydomain.com...Connecting with PsExec service on mxxxx01.mydomain.com...Starting C:\Program Files\Microsoft System Center 2012 R2\Operations 
Manager\Setup\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe on mxxxx01.mydomain.com...
C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe exited on mxxxx01.mydomain.com with error code 0.

It does not look pretty with the red output at the bottom, but it clearly worked with the ‘The approval of server new123.abc.com completed successfully.’ and ‘error code 0’ messages.
Further validation that it worked:

Get-SCOMGatewayManagementServer -Name $NewSCOMGWComputerFQDN

Like SSH, PSexec spins up an actual user session. So that was in fact the problem.

Thanks for the feedback Don.
Here’s the final code:

$myCred = Get-Credential -Username 'domain\user' # this is local admin on $ManagementServerFQDN
$ManagementServerFQDN  = 'mxxxx01.mydomain.com'
$NewSCOMGWComputerFQDN = 'new123.abc.com'
Write-Log 'Registering the',$NewSCOMGWComputerFQDN,'SCOM Gateway with the Management Group' Green,Cyan,Green $LogFile -NoNewLine
$Result = ..\PSTools\PsExec.exe \\$ManagementServerFQDN -u $MyCred.UserName -p $MyCred.GetNetworkCredential().Password -h "C:\Program Files\Microsoft System Center 2012 R2\Operations Manager\Setup\Microsoft.EnterpriseManagement.gatewayApprovalTool.exe" /ManagementServerName=$ManagementServerFQDN /GatewayName=$NewSCOMGWComputerFQDN /Action=Create *>&1
if ($Result) {
    if ($Result -match 'The gateway name already exists as a computer instance.') {
        Write-Log 'The gateway name already exists as a computer instance.' Yellow $LogFile
    } elseif ($Result -match 'completed successfully.') {
        Write-Log ($Result -match 'completed successfully.') Cyan $LogFile
    }                    
} else {
    Write-Log 'failed' Magenta $LogFile
} 

I redirected output from all pipelines to the stdio to hide the red stuff.
This produces nice and neat output like

Registering the new123.abc.com SCOM Gateway with the Management Group The approval of server new123.abc.com completed successfully.  

Now time for the dumb question:
I routinely use POSH-SSH PS module to remote into and work with Linux VMs. Are you saying we can connect to Windows computers via SSH?