pass credentials into powershell activity

chadlockwood
Kilo Sage

I'm trying to build a custom PowerShell activity that will run Invoke-RestMethod against my instance to pull an attachment to the MID server. I have a service account built in ServiceNow with permissions to do this. When I run my PowerShell script on the MID server from the PowerShell ISE, the script/credentials work fine.

Now I need to figure out how to get the credentials of the service account into my custom PowerShell activity so that my code can use them. The PowerShell script is being executed on the MID server using the MID Server Service account, but those credentials will not work for the REST request.

I believe that there will be an issue with getting the appropriate password data type from the JavaScript in the workflow, into the PowerShell. In my script, I am generating a credential object like this:

$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:SNC_restUser, (ConvertTo-SecureString -String $env:SNC_restPass -AsPlainText -Force)

This works perfectly if I hard-code the username and password into the script in clear text.

I have tried Credential Tagging, but I believe that is only used as the account that is running the whole script, not individual cmdlets within the code.

Does anyone have experience doing this or could tell me how to convert a password object in JavaScript into an appropriate PowerShell password object?

1 ACCEPTED SOLUTION

chadlockwood
Kilo Sage

The solution that I found turned out to be significantly simpler than I expected, thanks to the REST API Explorer.


In the explorer, you have the option of running a REST request as yourself or another user:


find_real_file.png


Select Send as another user, enter the credentials for your service account and click Send. You will then see your Request, the Response and the Response Body. In the Request headers, you will see an Authorization key with a basic authentication hash:


find_real_file.png



The hash, including the word 'Basic' is all you need. It is important to note here that once you have run this request you have essentially impersonated your service account and you will have to logout of your instance and back in.



  There are a couple of ways you can use the basic authentication hash. For testing purposes, I hardcoded it into my PowerShell code:


$basicAuth = "Basic YWJlbC50dXRlcjpQYXNzd29yZDEyMyE="


$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"


$headers.Add('Authorization',$authorization)


$headers.Add('Accept','application/json')



Invoke-RestMethod -Uri $uri -Headers $headers



You could also code it into your workflow and pass it as a string to your PowerShell activity or, better yet, create a system property to hold the hash value, and getProperty in your workflow to pass the value to your activity. That way, it is easier to maintain should you need to change the credentials you are using.


View solution in original post

8 REPLIES 8

Hi Kaniska



I never tried the code/I have only passed the code to this thread.


I haven't got the time to look into it right now - could you please follow the link to the origin post? [EDIT: I see you already did]:


AD orchestration authentication $cred is null



If you feel you have the time, and you learn something, don't hesitate to update this post with what you learn.



SIncirely,



Anders


I know I'm late to the party and all, but the method you use, with the Basic followed by the hash, is just as bad as putting the password in as plain text.  That hash is a Base64Encoding of your username:password.  For instance "username:password" encodes to "dXNlcm5hbWU6cGFzc3dvcmQ=", and is very easily decoded back to "username:password".  It's not encrypted in any way, and anyone who knows this now has access to your username and password. Luckily, the example you give is only "abel.tuter:Password123!", which isn't obviously an account that is secured.

 

Rick Seiden

brantgluth
Kilo Expert

Probably a little late but for passwords on PowerShell activities, I pass the following depending o   what I need the PowerShell to do



#o'B 22 Nov 2016 14:53 temporary


try


{


  $username = "${activityInput.username}"


  $password = convertto-securestring -String "${activityInput.passowrd}" -AsPlainText -Force


  $secstr = New-Object -TypeName System.Security.SecureString


  # $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}


  $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password


}


catch{


  $returnError = "Issues setting security: " + $_


  #exit


  }


Brant,

This came up again; this time trying to connect to Outlook Web Access PowerShell. Although the MID server service credentials have permissions to accomplish this, PowerShell doesn't use them to connect. I used your suggestion to develop a solution:

I created two system properties: username(string) and password(password)

In my custom PowerShell activity, I put:

$username = "${activityInput.username}"
$secpasswd = ConvertTo-SecureString "${activityInput.password}" -AsPlainText -Force
$cred = New-Object -typename System.Management.Automation.PSCredential($username,$secpasswd)

and passed $cred to New-PSSession to connect to OWA.

To get the sys_properties into the custom activity, I first set scratchpad variables to those values using:

workflow.scratchpad.username = gs.getProperty("username");
workflow.scratchpad.password = gs.getProperty("password");

but as you can imagine, that showed the password in clear text in the Workflow context. So, instead, in the input fields of the custom activity, I put:

${gs.getProperty("username"}

As far as I can tell, the password is not visible in clear text now. I do not see it in the context, nor did it appear in the logs on the MID server. However, if I add this line to the PowerShell code:

Write-Host "${activityInput.password}"

it will print the password in clear text. So, I'm not sure how secure this actually is. I guess since the password system property is "secured"(obfuscated) and I'm not actually printing the password out in my PowerShell code, it could be acceptable, but I would like to feel more confident. It would be better if I could pass a secured string from the workflow into the PowerShell activity, that the PowerShell code could recognize as a credential object without ever being clear text.

Thanks for your input.