Using Jenkins defined variables in PowerShell block - powershell

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')
}

Related

Assign value to powershell variable within Jenkins pipeline

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.

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

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

Is there any way to clone Powershell Runspace object

I want to know if it is possible to create a new Powershell Runspace object from an old one.
I'm am going to do some powershell operations concurrently. I create powershell runspace every time and run certain commands. Let's say the first 5 commands are same for all operations. If I could run those commands only once for all operations and send a copy of the runspace to the multi threading method, it would be more efficient.
Means, I run some commands through a pipeline first.
Runspace runspace = RunspaceFactory.CreateRunspace()
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("$var = 5"); //those 5 initial commands
pipeline.Invoke();
Now, I want to run certain commands concurrently.
Parallel.For(0, 5, new ParallelOptions { }, i => concurrentOperations(runspace, i));
The concurrentOperations method has been defined as this
private static void concurrentOperations(Runspace runspace, int i)
{
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("$newVar = $var + " + i + "; $newVar"); //newer commands which differs for each operation
runspace.Open();
System.Collections.ObjectModel.Collection<PSObject> result = pipeline.Invoke();
foreach (PSObject obj in result)
{
Console.WriteLine("obj" + i + " : " + obj);
}
}
And now I encounter an exception that, "Pipelines cannot be run concurrently".
So, If I could make a copy of the runspace, the pipelines will be created for different runspaces only. But runspace doesnot have Clone() method in it.
Is there any way that I could achive this?

Pass ProcessParameters runtime (MSBuildArguments) using Powershell to tfs 2010 build definitions

I am executing builds using powershell script. I need to pass the process parameters run time based on the commandline arguments passed to the script. I am using TFS 2010.
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
$projectName = "test"
$buildName = "test.Build"
$tfsServer="xxx"
$tfsInstance = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($tfsServer)
$buildService = $tfs.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$buildDefinations = $buildService.QueryBuildDefinitions($projName)
Loop through all the builds to find the one we are looking for
foreach ($build in $buildDefinations)
{
Get the name of this build instance
$bNameInstance = $build.Name
$ClientName = "test1" #default set in the builddefination is "/p:xxx=test"
#Get the process parameters. I need to update the default value. How can we process the dictionary and update the value
$bMSBuildArguments = $build.ProcessParameters
#Once setting is done."/p:xxx=test1"
$build.ProcessParameters = $bMSBuildArguments
[Void]$buildService.QueueBuild($build)
}
I need help in updating the processparameters using the powershell code. I came across the C# (http://blogs.msdn.com/b/jpricket/archive/2010/03/25/tfs2010-queuing-a-build-from-code-with-custom-process-parameter-values.aspx)solution but not able convert that to Powershell
The answer is in the blog post provided. Try something like this:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Workflow")
$request = $build.CreateBuildRequest()
$process = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::DeserializeProcessParameters($build.ProcessParameters)
#make changes to your process parameters in $process
$process.Item("asdf") = "new value"
$request.ProcessParameters = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::SerializeProcessParameters($process)
$buildService.QueueBuild($request)