I've spent a considerable amount of time with SolarWinds support, digging around in Thwack and trying to engineer a work-around on my own. Unfortunately these were all dead-ends. The VBS script option that is mentioned HERE worked but had several limitations that rendered it a useless alternative for us. (Namely passing credentials securely)
What's maddening is that this used to work just fine in our previous environment (v 2018.2).
- Windows Server 2012 R2
- PowerCLI Version: 11.2.0.12780525
- PowerShell Version: 5.1.14393.3053
Then when we upgraded to 2019.2, it longer worked in our new environment.
- Windows Server 2016
- PowerCLI Version: 11.3.0.13964830
- PowerShell Version: 5.0.10586.117
I strongly believe it's an impersonation issue. Despite the logging showing us it is running under our Orion Service account, it’s behaving as if the script is running under the NT Authority\System account. The only time the script fails is when it’s being triggered by SolarWinds OR when being run (via PSEXEC) under the local system account. Which totally makes sense, as that account is locked down so it cannot execute commands or modules that have the ability to execute code on remote machines. Unfortunately, SolarWinds technical support is dismissing this as a "custom script" issue.
In any event, all of this to say that I have found what I believe to be a more flexible work-around than the VBS script I eluded too earlier. It consists of 3 parts.
Part 1 - Trigger the "Call" script from your Alert.
Example:
C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -File "C:\scripts\Restart-Citrix-VM.ps1" -Computer ${NodeName}
Part 2 - Run the call script to pull in your encrypted credentials and then execute your target script.
param([string]$Computer)
$CredsPath = "C:\scripts\Creds"
$Script = "C:\scripts\Restart-Citrix-VM.ps1 -Computer $Computer"
$password = Get-Content $CredsPath\password.txt | ConvertTo-SecureString -Key (Get-Content $CredsPath\aes.key)
$credential = New-Object System.Management.Automation.PsCredential("corp\<username>",$password)
Start-Process -FilePath powershell -ArgumentList $Script -Credential $credential
Part 3 - Execute your target script - Make sure to also include the param line here as well
param([string]$Computer)
$ErrorActionPreference = "Continue"
Start-Transcript -path C:\scripts\Output.txt -append
<your script code>
Stop-Transcript
I personally recommend throwing that "Start-Transcript" line in your scripts, so you can easily troubleshoot and diagnosis any issues you run into.
To save you the time looking it up, Here's the process I use to encrypt credentials for Part 2 in Powershell.
#Create Password File
(get-credential).password | ConvertFrom-SecureString | set-content C:\Temp\password.txt
#Create AES.Key File
$Key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file C:\Temp\aes.key
#Merge the AES Key w/ Password File
(get-credential).Password | ConvertFrom-SecureString -key (get-content C:\Temp\aes.key) | set-content C:\Temp\password.txt
I sincerely hopes this helps some other folks out there!
Update - 9/4/2019
I spoke with an application engineer this afternoon who confirmed that this not intended behavior and he will be logging it as an issue to hopefully be addressed in a future update / release.