Execute a Powershell Script from a Powershell Script with Different Credentials


Recently I have been in a few conversations where we needed to execute a PowerShell script from within a PowerShell script but have the second or child script execute under different security credentials.

Why the hell do you need to do that? In my case we are orchestrating a solution using AWS micro services focusing on Step Functions and Lambda. Some of the code that we need to execute has been written in PowerShell by other teams and we don't want to own that code, we just want to execute it.

During our automated deployments of our EC2 servers we clone a few GIT repositories that contain the PowerShell code we need to execute. Because our servers are fully configured during the build we can use AWS Systems Manager to shell into the server to execute a PowerShell script and pass data into it and then get the output all from within a Lambda function.

Note: AWS support has informed me PowerShell support directly in Lambda is on the road map and might be released this year. Maybe at the next reInvent?

After much testing with Start-Process and Invoke-Command I took a step back to see if we could just spawn a new thread. We can!

Here is the full snippet:

#this usage is to emulate you needing to pass a bunch of arguments across
#usage would be: powershell .\StartHere.ps1 .\Script_2.ps1 -fname shawn -lname woodward
$file = $args

#create the credential object.
#note the password file was encrypted with AES so it can be shared across machines.
#setting up credentials
#part 1 - https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-1/
#part 2 - https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/
$UserName = "myusername@mydomain.com"
$PasswordFile = ".\Password.txt"
$KeyFile = ".\AES.key"
$key = Get-Content $KeyFile
$pw = Get-Content $PasswordFile | ConvertTo-SecureString -Key $key

#Docs on System.Diagnostic.ProcessStartInfo Class === https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "powershell"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = $file
$pinfo.Username = $UserName
#$pinfo.PasswordInClearText = "CLEAR_TEXT_PASSWORD"
$pinfo.Password = $pw #this is using a secure password string
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
$p.WaitForExit()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode

Note: The above code snippet was pasted directly from Visual Studio Code

In the above code please imagine it is stored in a file named StartHere.ps1. Everything after that is going to be treated as an argument but that argument is really going to be the code executed in the new thread that is created.

Don't forget that PowerShell is just some of the classes that make up the .NET Framework. The cool part is you still can access any class you want from your script which is what I have done here.

You will notice I left links to other articles that helped me develop this code. I do that so if I ever need to make a change or someone else needs to modify it they have all the data they need. I dislike scripters / developers who find stuff on the internet and then try and pass it off as their own.

Any questions please comment below. Thanks and I hope this helps.



Execute a Powershell Script from a Powershell Script with Different Credentials Execute a Powershell Script from a Powershell Script with Different Credentials Reviewed by Shawn Woodward on 1:23 PM Rating: 5

No comments:

Powered by Blogger.