Setting output variable using newman / postman is getting cut off - azure-devops

I have an output variable siteToDeploy and siteToStop. I am using postman to run a test script against the IIS Administration API. In the test portion of one of the requests I am trying to set the azure devops output variable. Its sort of working, but the variable value is getting cut off for some reason.
Here is the test script in postman:
console.log(pm.globals.get("siteName"))
var response = pm.response.json();
var startedSite = _.find(response.websites, function(o) { return o.name.indexOf(pm.globals.get("siteName")) > -1 && pm.globals.get("siteName") && o.status == 'started'});
var stoppedSite = _.find(response.websites, function(o) { return o.name.indexOf(pm.globals.get("siteName")) > -1 && o.status == 'stopped'});
if(stoppedSite && startedSite){
console.log('sites found');
console.log(stoppedSite.id)
console.log('##vso[task.setvariable variable=siteToDeploy;]' + stoppedSite.id);
console.log('##vso[task.setvariable variable=siteToStop;]' + startedSite.id);
}
Here is the output form Newman:
Here is the output from a command line task echoing the $(siteToDeploy) variable. It's getting set, but not the entire value.
I've tried escaping it, but that had no effect. I also created a static command line echo where the variable is set and that worked fine. So I am not sure if it is a Newman issue or Azure having trouble picking up the varaible.

The issue turned our to be how Azure is trying to parse the Newman console log output. I had to add an extra Powershell task to replace the ' coming back from the Newman output.
This is what is looks like:
##This task is only here because of how Newman is writing out the console.log
Param(
[string]$_siteToDeploy = (("$(siteToDeploy)") -replace "'",""),
[string]$_siteToStop = (("$(siteToStop)") -replace "'","")
)
Write-Host ("##vso[task.setvariable variable=siteToDeploy;]{0}" -f ($_siteToDeploy))
Write-Host ("##vso[task.setvariable variable=siteToStop;]{0}" -f ($_siteToStop))

Related

Parse data using Powershell and convert to Json

Background.
i have IBM CDC Replication engine and i need to check subscriptions status by using Zabbix.
Im calling subs status by cmd.exe /C "C:\Program Files\IBM\InfoSphere Data Replication\Management Console\bin\chcclp.exe" -f c:\CDC_Check.txt where CDC_Check.txt is script for that chcclp CLI
//Check the status of all subscriptions
//Source datastore: ***
//Target datastore: ***
chcclp session set to cdc;
// Turn on verbose output.
set verbose;
// Setting variables.
set variable name "ACCESS_HOSTNAME" value "";
set variable name "ACCESS_PORT" value "";
set variable name "ACCESS_USERNAME" value "";
set variable name "ACCESS_PASSWORD" value "";
set variable name "SOURCE_DATASTORE" value "";
set variable name "TARGET_DATASTORE" value "";
// Connecting to Access Server.
connect server
hostname "%ACCESS_HOSTNAME%"
port "%ACCESS_PORT%"
username "%ACCESS_USERNAME%"
password "%ACCESS_PASSWORD%";
// Connecting to the source and target datastores.
connect datastore name "%SOURCE_DATASTORE%";
connect datastore name "%TARGET_DATASTORE%";
// Setting the datastore context.
select datastore name "%SOURCE_DATASTORE%" context source;
select datastore name "%TARGET_DATASTORE%" context target;
// List replication state and latency of all subscriptions.
monitor replication;
// Disconnecting from datastores and Access Server.
disconnect datastore name "%SOURCE_DATASTORE%";
disconnect datastore name "%TARGET_DATASTORE%";
// Disconnect from Access Server and terminate the script.
disconnect server;
exit;
and im receiving following result:
Im trying to parse Subscription + Status and move it to Json for next integration with zabbix.
Im very new in PS so i still have no normal progress.
I understand idea that i need to capture anything that going under SUBSCRIPTIONS and STATE and write it to Json.
The first step would be to redirect the output of the app so you can read it in for parsing.
cmd.exe /C "C:\Program Files\IBM\InfoSphere Data Replication\Management Console\bin\chcclp.exe" -f c:\CDC_Check.txt > C:\temp\file.log
Then you can use the get Get-Content cmdlet to get it in your console session
$fileContent = Get-Content -Path "C:\temp\file.log"
Once it's in an array you can parse it like so.
$i=0
$fileContent | %{
$i++
if($_ | Select-String -Pattern "SUBSCRIPTION STATE" -CaseSensitive){
$headerIndex = $i
}
}
$headerIndex += 2 #start of report data to capture
This loop continues until it finds the blank line in the output
$hashObj= #{}
for ($x = $headerIndex; $fileContent[$x].length -gt 1 ;$x++){
$hashObj.Add("$($fileContent[$x].Substring(0,19).Trim(' '))","$($fileContent[$x].Substring(20,19).Trim(' '))")
}
#converts your hashtable to json object
$jsonObj = $hashObj | convertto-json
Not entirely sure how you need the json formatted but this will be what to expect your output to be similar to
{
"S_ACC_D": "Mirror Continuous",
"S_ACC_E": "Mirror Continuous",
"S_ACC_A": "Mirror Continuous",
"S_ACC_B": "Mirror Continuous",
"S_ACC_C": "Mirror Continuous"
}

Powershell script not working when included in Jenkins Pipeline Script

What I am trying to achieve with Powershell is as follows:
Increment the Build Number in the AssemblyInfo.cs file on the Build Server. My Script looks like below right now after over a 100 iterations of different variations I am still unable to get it to work. The script works well in the Powershell console but when included into the Jenkins Pipeline Script I get various errors that are proving hard to fix...
def getVersion (file) {
def result = powershell(script:"""Get-Content '${file}' |
Select-String '[0-9]+\\.[0-9]+\\.[0-9]+\\.' |
foreach-object{$_.Matches.Value}.${BUILD_NUMBER}""", returnStdout: true)
echo result
return result
}
...
powershell "(Get-Content ${files[0].path}).replace('[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+',
${getVersion(files[0].path)})) } | Set-Content ${files[0].path}"
...
How about a groovy approach (with Jenkins keywords) instead of PowerShell:
def updtaeAssemblyVersion() {
def files = findFiles(glob: '**/AssemblyInfo.cs')
files.each {
def content = readFile file: it.path
def modifedContent = content.repalceAll(/([0-9]+\\.[0-9]+\\.[0-9]+\\.)([0-9]+)/,"\$1${BUILD_NUMBER}")
writeFile file: it.path, text: modifedContent
}
}
It will read all relevant files and replace only the build section of the version for every occurrence that matches the version regex.

Cake Task output log to file

I have a set of Tasks inside a build.cake file and I would like to capture the log output from the console into a log file. I know it's possible to use the OnError() function to output errors to file but I would like to output everything to a log file, not just errors.
Below is an example of the build.cake file.
#load "SomeTask.cake"
#load "SomeOtherTask.cake"
var target = Argument("target", "Default");
var someTask = Task("SomeTask")
.Does(() =>
{
SomeMethodInsideSomeTask();
});
var someOtherTask = Task("SomeOtherTask")
.Does(() =>
{
SomeOtherMethodInsideSomeOtherTask();
});
Task("Default")
.IsDependentOn(someTask)
.IsDependentOn(someOtherTask);
RunTarget(target);
N.B. The Tasks are not running any sort of MSBuild commands so it's not possible to use MSBuildFileLogger.
How about pipe the stdout to a file i.e.
./build.ps1 > log.txt
Have you heard about tee ?
It reads standard input and writes it to both standard output and one or more files

Powershell dsacls on success or fail

I have PowerShell script which delegates powers of security group for the selected OU via dsacls.
All works fine but i want to output a JSON response for success delegation (without all dsacls access list and object info) and for error just information.
How i run dcals:
dsacls "OU=Organization,DC=domain,DC=tld" /I:S /G GroupName:RPWP;sn;user
How to check now is dsacls run correct delegate and return via ConvertTo-Json method?
Is there another option than checking response string of dsacls?
Thanks.
maybe something like this:
$res = dsacls "OU=Organization,DC=domain,DC=tld" /I:S /G GroupName:RPWP;sn;user
#{ success = $?
error = if (!$?) { [string]$res } else { "" }
} | ConvertTo-Json
the $? variable contains the success status of the last executed command (true or false)

How to get list of TFS builds running at the moment from command line?

I'm trying to automate the deployment process, and as part of it, I need to run my release build from command line. I can do it, using command like
.\TFSBuild start http://server-name:8080/tfs/project-collection project-name build-name priority:High /queue
It even returns some code for the queued build — Build queued. Queue position: 2, Queue ID: 11057.
What I don't know, is how to get info about currently running builds, or about the state of my running build from powershell command line? The final aim is to start publishing after that build completes.
I've already got all necessary powershell scripts to create the deployment package from the build results, zip it, copy to production and install there. All I need now — to know when my build succeedes.
This function will wait for a build with the Queue ID given by TFSBuild.exe:
function Wait-QueuedBuild {
param(
$QueueID
)
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Build.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Client')
$uri = [URI]"http://server-name:8080/tfs/project-collection"
$projectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($uri)
$buildServer = $projectCollection.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$spec = $buildServer.CreateBuildQueueSpec('*','*')
do {
$build = $buildServer.QueryQueuedBuilds($spec).QueuedBuilds| where {$_.Id -eq $QueueID}
sleep 1
} while ($build)
}
You can get the id returned by TFSBuild.exe, then call the function.
$tfsBuild = .\TFSBuild start http://server-name:8080/tfs/project-collection project-name build-name priority:High /queue
Wait-QueuedBuild [regex]::Match($tfsBuild[-1],'Queue ID: (?<id>\d+)').Groups['id'].Value
Using the work by E.Hofman available here it is possible to write a C# console app that uses TFS SDK and reveals if any build agent is currently running as follows:
using System;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
namespace ListAgentStatus
{
class Program
{
static void Main()
{
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://TFSServer:8080"));
var buildServer = teamProjectCollection.GetService<IBuildServer>();
foreach (IBuildController controller in buildServer.QueryBuildControllers(true))
{
foreach (IBuildAgent agent in controller.Agents)
{
Console.WriteLine(agent.Name+" is "+agent.IsReserved);
}
}
}
}
}
The parameter .IsReserved is what toggles to 'True' during execution of a build.
I 'm sorry my powershell skills are not good enough for providing with a PS variant of the above. Please take a look here, where the work by bwerks might help you do that.
# load classes for execution
[Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client") | Out-Null
# declare working variables
$Uri = New-Object System.Uri "http://example:8080/tfs"
# get reference to projection collection
$ProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($Uri)
# get reference to build server
$BuildServer = $ProjectCollection.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
# loop through the build servers
foreach($Controller in $BuildServer.QueryBuildControllers($true))
{
# loop through agents
foreach($BuildAgent in $Controller.Agents)
{
Write-Host "$($BuildAgent.Name) is $($BuildAgent.IsReserved)"
}
}