Assign value to powershell variable within Jenkins pipeline - powershell

I came across several documents on how to run a Powershell script within Jenkins pipeline and how to capture output.
However I want to use the captured output for next node powershell script.
e.g.
node {
def msg = powershell(returnStdout: true, script: 'Write-Output "PowerShell is mighty!"')
}
Now I want to use msg in the next node within Powershell script. Like if we can assign it to a powershell variable and then perform operations with that variable.
Any pointers on how this can be achieved?

You can assign the powershell output to an environment variable and use that in the subsequent nodes:
node {
env.msg = powershell(returnStdout: true, script: 'Write-Output "PowerShell is mighty!"')
}
node {
def output = powershell(returnStdout: true, script: '''
$message = ($env:msg).trim()
Write-Output $message
''')
println(output)
}
Notice the env prefix before variable msg. You can retrieve the variable within powershell in next node using $env: prefix followed by variable name. Don't forget to trim the variable (.trim()) within powershell to remove newline.

Related

Using Jenkins defined variables in PowerShell block

For example, there is a Jenkins stage with defined variable - jenkinsVariable = 5
How can I access that variable in the powershell block? Is that possible like this or I need to call powershell.ps1 with parameters in order to transfer variable from jenkins to powershell area?
stage (testStage)
{
def jenkinsVariable = 5;
def result = powershell (returnStdout: true, script: 'Write-Output jenkinsVariable')
}

how do i get a variable out of powershell in jenkins declarative pipeline?

steps {
script{
env.StorysTested = ''
try{
powershell('''
//some code here
foreach ( $item in $Comments )
{
//some code here
//assigning a new value to StoryTested env variable
$env:StorysTested = "some value"
}
//below line works fine and displays the value
Write-Output "Stories tested : $env:StorysTested"
''')
//below null value is displayed for StorysTested``
echo " From Grrovy : ${env.StorysTested}"
}
catch(err)
{
throw err
}
}
I am using a jenkins declarative pipeline.
In the above code i m trying to use the value of $env:StorysTested in groovy which was assigned in powershell. Is there any way i can retain a variable value that was assigned in powershell, after the powershell execution is over. storing it in env variable was one way i thought of but clearly that didnt work.
If you set an environment variable using $env:StorysTested = "some value", this variable is stored for the powershell process and is not permanent or visible outside this process.
To create more permanent environment variables (i.e., user-level or machine-level) you need to use the .NET Framework and the SetEnvironmentVariable method:
[Environment]::SetEnvironmentVariable("StorysTested", "some value", "User")
or
[Environment]::SetEnvironmentVariable("StorysTested", "some value", "Machine")
To delete from within PowerShell, you use the same .NET method and assign a $null value to the variable like this:
[Environment]::SetEnvironmentVariable("StorysTested",$null,"User") # or "Machine" of course
Hope that helps

Return output from Powershell script to UIPath using Invoke power shell

I am trying to get a value from an input box from a Powershell script back to a UI Path Sequence. I have created a simple sequence as an example. Yes, I know I could do this all in UI Path, I am just using an easy example as a way to try and test this for future use cases. Here is my sequence:
My text file from "Read text file" is:
$test = "Desktop/PassingArgs2of2.ps1 -Message foo"
Invoke-Expression -Command $test
The activity in UiPath looks like so:
The psCmd that I am running in the Invoke power shell activity looks like this:
Param(
[parameter(Mandatory=$true)]
[string]
$Message)
try{
$Global:fooVar = $null
function Test-InputBox(){
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$msg = "fooMsg"
$title = "fooTitle"
$localtest = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
$Global:fooVar = $localtest.ToString()
}
Test-InputBox
}
catch{}
I tried setting fooVar equal to testLocal in the PowerShellVariables within Invoke power shell and then writing it, but that did not work.
Basically I want to get fooVar back into UI Path. Any help would be greatly appreciated. Thank you!
You're almost there. First, your Powershell script has to return a value. Take this for example:
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$title = 'Your title goes here'
$msg = 'Your favorite color:'
$text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
return $text
Here's the script in action (note that I called it twice and provided "red" the first time:
Then, just use this script directly in the Invoke Powershell activity. Note that the most important part here is the Output property - here, I decided to go for an array of strings. Naturally, as we only return a single value, you can just access the text provided by the user by accessing output(0).ToString().

Powershell - persist variable outside of function

I'm trying to import an xml file and store as a variable for the remainder of a powershell session. The import is obviously successful but the variable content does not persist outside of the function.
Function auth
{
$cred = import-clixml -Path c:\temp\cred.xml
}
try this:
Function auth
{
$global:cred = "test"
}
auth
$global:cred
You can use globals as Esperento57 suggests or you can do this
function auth
{
return 'test'
}
$cred = auth
More succinct:
function auth
{
'test'
}
$cred = auth
You need to declare the variable outside the scope of the function first and then inside the function explicitly tell the variable to update using the script:var method.
Here's the example is taken from https://www.kongsli.net/2013/04/25/powershell-gotchas-refer-to-variables-outside-a-function/ to which credit is given.
The thing is that we have to explicitly tell Powershell to update the variable in the parent scope instead of creating a new variable in the current scope.
$x = 1
function changeit {
"Changing `$x. Was: $x"
$script:x = 2
"New value: $x"
}
"`$x has value $x"
changeit
"`$x has value $x"
If you need to do this but with a number of functions and variables, you can place them all into a script and then dotsource the script.
Imagine a script like this:
#MyDevFunctions.ps1
$myImportantVar = "somevar"
$myOtherVar = "ABC123"
Function Get-MyCoolValue(){$myImportantVar}
Write-Host "Finished Loading MyDevFunctions"
If you wanted to run this, and then also persist the values of the variables and also the functions themselves, from your parent script you simply invoke it like so:
PS > . .\MyDevFunctions.ps1
"Finished Loading MyDevFunctions"
PS > $myOtherVar
ABC123
PS> Get-MyCoolValue
someVar

Powershell arguments list passing like -a <args list> -d <args list>

I want to write a powershell ps1 script, which needs 2 argument sets,(-a -d) and each can have upto n attributes. How to implement that?
example : DoTheTask -a <task name 1> <task name 2> ... -d <machine name 1> <machine name 2>...
You can do this:
param(
[string[]]$a,
[string[]]$d
)
write-host $a
write-host ----
write-host $d
Then you can call DoTheTask -a task1,task2 -d machine1,machine2
Can you organize your task names and machines names in such a way that they can be put in to a single string with delimiters.
In other words, could your -a argument be a string a comma-separated task names and your -d argument be a string of comma-separated machine names? If so, then all you need to do is parse the string into its components at the start of your script.
If you are passing these arguments to the script itself, you could leverage the $args internal variable, though key/value mapping will be a little trickier since PowerShell will interpret each statement as an argument. I suggest (like others) that you use another separator so that you can do the mappings easier.
Nonetheless, if you want to continue doing it this way, you can use a function like the below:
Function Parse-Arguments {
$_args = $script:args # set this to something other than $script:args if you want to use this inside of the script.
$_ret = #{}
foreach ($_arg in $_args) {
if ($_arg.substring(0,1) -eq '-') {
$_key = $_arg; [void]$foreach.moveNext() # set the key (i.e. -a, -b) and moves to the next element in $args, or the tasks to do for that switch
while ($_arg.substring(0,1) -ne '-') { # goes through each task until it hits another switch
$_val = $_arg
switch($_key) {
'-a' {
write-host "doing stuff for $_key"
$ret.add($_key,$_val) # puts the arg entered and tasks to do for that arg.
}
# put more conditionals here
}
}
}
}
}