Using the Flow Designer PowerShell Step
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
an hour ago
Hello all,
I have stumbled upon the PowerShell Step in Flow Designer. https://www.servicenow.com/docs/r/yokohama/build-workflows/workflow-studio/powershell-step-action-de... What I am really struggling with is the connection information. I do not need to execute on a particular midserver as far as I know, I just need A server to run the below code.
The below is my powershell script.
param(
[string]$ResponseBody,
[string]$EncryptedSecret,
[string]$ApiSecret = "",
[switch]$SelfTest
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Get-OpenSslKeyIvFromPassphrase {
param(
[Parameter(Mandatory = $true)]
[byte[]]$PassphraseBytes,
[Parameter(Mandatory = $true)]
[byte[]]$Salt,
[int]$KeyLengthBytes = 32,
[int]$IvLengthBytes = 16
)
$md5 = [System.Security.Cryptography.MD5]::Create()
try {
$derived = New-Object System.Collections.Generic.List[byte]
$prev = [byte[]]@()
while ($derived.Count -lt ($KeyLengthBytes + $IvLengthBytes)) {
$input = New-Object byte[] ($prev.Length + $PassphraseBytes.Length + $Salt.Length)
[Array]::Copy($prev, 0, $input, 0, $prev.Length)
[Array]::Copy($PassphraseBytes, 0, $input, $prev.Length, $PassphraseBytes.Length)
[Array]::Copy($Salt, 0, $input, $prev.Length + $PassphraseBytes.Length, $Salt.Length)
$prev = $md5.ComputeHash($input)
$derived.AddRange($prev)
}
$all = $derived.ToArray()
$key = New-Object byte[] $KeyLengthBytes
$iv = New-Object byte[] $IvLengthBytes
[Array]::Copy($all, 0, $key, 0, $KeyLengthBytes)
[Array]::Copy($all, $KeyLengthBytes, $iv, 0, $IvLengthBytes)
return @{ Key = $key; IV = $iv }
}
finally {
$md5.Dispose()
}
}
function Decrypt-CryptoJsAesPassphrase {
param(
[Parameter(Mandatory = $true)]
[string]$CipherTextBase64,
[Parameter(Mandatory = $true)]
[string]$Passphrase
)
$raw = [Convert]::FromBase64String($CipherTextBase64)
if ($raw.Length -lt 16) {
throw "Cipher text too short."
}
$header = [System.Text.Encoding]::ASCII.GetString($raw, 0, 8)
if ($header -ne "Salted__") {
throw "Unsupported format. Expected OpenSSL salted format that starts with Salted__."
}
$salt = New-Object byte[] 8
[Array]::Copy($raw, 8, $salt, 0, 8)
$cipherBytes = New-Object byte[] ($raw.Length - 16)
[Array]::Copy($raw, 16, $cipherBytes, 0, $cipherBytes.Length)
$passBytes = [System.Text.Encoding]::UTF8.GetBytes($Passphrase)
$derived = Get-OpenSslKeyIvFromPassphrase -PassphraseBytes $passBytes -Salt $salt
$aes = [System.Security.Cryptography.Aes]::Create()
try {
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$aes.Key = $derived.Key
$aes.IV = $derived.IV
$decryptor = $aes.CreateDecryptor()
try {
$plainBytes = $decryptor.TransformFinalBlock($cipherBytes, 0, $cipherBytes.Length)
}
catch [System.Security.Cryptography.CryptographicException] {
throw "Decrypt failed (invalid padding). This usually means the encrypted value and ApiSecret do not match, or the value was not encrypted with CryptoJS passphrase mode."
}
return [System.Text.Encoding]::UTF8.GetString($plainBytes)
}
finally {
$aes.Dispose()
}
}
function Encrypt-CryptoJsAesPassphrase {
param(
[Parameter(Mandatory = $true)]
[string]$PlainText,
[Parameter(Mandatory = $true)]
[string]$Passphrase
)
$salt = New-Object byte[] 8
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($salt)
$passBytes = [System.Text.Encoding]::UTF8.GetBytes($Passphrase)
$derived = Get-OpenSslKeyIvFromPassphrase -PassphraseBytes $passBytes -Salt $salt
$aes = [System.Security.Cryptography.Aes]::Create()
try {
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$aes.Key = $derived.Key
$aes.IV = $derived.IV
$encryptor = $aes.CreateEncryptor()
$plainBytes = [System.Text.Encoding]::UTF8.GetBytes($PlainText)
$cipherBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length)
$prefix = [System.Text.Encoding]::ASCII.GetBytes("Salted__")
$combined = New-Object byte[] ($prefix.Length + $salt.Length + $cipherBytes.Length)
[Array]::Copy($prefix, 0, $combined, 0, $prefix.Length)
[Array]::Copy($salt, 0, $combined, $prefix.Length, $salt.Length)
[Array]::Copy($cipherBytes, 0, $combined, $prefix.Length + $salt.Length, $cipherBytes.Length)
return [Convert]::ToBase64String($combined)
}
finally {
$aes.Dispose()
}
}
if ($SelfTest) {
$expected = "my-test-secret"
$encrypted = Encrypt-CryptoJsAesPassphrase -PlainText $expected -Passphrase $ApiSecret
$response = @{ encryptedSecret = $encrypted } | ConvertTo-Json -Compress
$jsonData = $response | ConvertFrom-Json
$newencryptedSecret = $jsonData.encryptedSecret
$newSecret = Decrypt-CryptoJsAesPassphrase -CipherTextBase64 $newencryptedSecret -Passphrase $ApiSecret
if ($newSecret -ne $expected) {
throw "Self-test failed: decrypted value does not match expected."
}
$result = @{ decryptedSecret = $newSecret; message = "Self-test passed." } | ConvertTo-Json -Compress
Write-Host $result
return
}
if ([string]::IsNullOrWhiteSpace($EncryptedSecret)) {
if ([string]::IsNullOrWhiteSpace($ResponseBody)) {
throw "Provide -EncryptedSecret directly, -ResponseBody with JSON containing encryptedSecret, or run with -SelfTest."
}
$jsonData = $ResponseBody | ConvertFrom-Json
$newencryptedSecret = $jsonData.encryptedSecret
}
else {
$newencryptedSecret = $EncryptedSecret
}
$newSecret = Decrypt-CryptoJsAesPassphrase -CipherTextBase64 $newencryptedSecret -Passphrase $ApiSecret
$result = @{ decryptedSecret = $newSecret } | ConvertTo-Json -Compress
Write-Host $result
0 REPLIES 0