How to validate empty field in azure task in build pipeline using powershell - azure-pipelines-release-pipeline

I'm creating new VSTS/TFS extension in azure build pipeline.
In that extension one field accepts a file path and it is optional field.
In powershell script, i want to validate the field, if no input is provided then i have to ignore, otherwise i have to check whether input is path of .config file or not.
$ConfigFileName = Get-VstsInput -Name 'ConfigFilePath'
if (!(Test-Path $ConfigFileName))
{
Write-Host "Configuration file doesn't exist."
"##vso[task.complete result=Failed]"
throw "Configuration file doesn't exist."
}
if([IO.Path]::GetExtension($ConfigFileName) -ne '.config')
{
Write-Host "Invalid configuration file.File type must be of .config"
"##vso[task.complete result=Failed]"
throw "Invalid configuration file.File type must be of .config"
}
I have validated like above, but when user not provided any input then also the $ConfigFileName variable filled with mapping path that is $ value.
How to check if input provided to that field is empty or not?

For filePath type input field, the default value is source directory (Build.SourcesDirectory, e.g. D:\a\1\s). So, you could check whether the value is not equal to the source directory.
For example:
{
"name": "filePathSelect",
"type": "filePath",
"label": "test select Path",
"required": false,
"defaultValue": "",
"helpMarkDown": "test select path"
}
PowerShell:
Write-Host "get select file path value"
$fileSelectPathValue = Get-VstsInput -Name filePathSelect
Write-Host "select file path value is $fileSelectPathValue"
Write-Host "default path $env:Build_SourcesDirectory"
if([string]::IsNullOrEmpty($fileSelectPathValue)){
Write-Host "Selected File path is empty"
}
elseif(($fileSelectPathValue -eq $env:Build_SourcesDirectory) -or !(Test-Path $fileSelectPathValue))
{
Write-Host "select path is invalid"
}
else
{
Write-Host "select path is valid"
}
If the input type is string, then you just need to check whether the value is null or empty [string]::IsNullOrEmpty.

Related

powershell cant get json key / value

Hello I have a json file below:
{
"supports": {},
"dependencies": {
"AST.NxTestware.main": "1.1.0",
"otherPackagenName": "7.7.7"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile78": {}
}
}
and I am trying to write a .ps1 powershell script that will look at every item under 'dependencies', check if the name matches, and if so, retrieve the version number.
but I am having trouble parsing through each item in 'dependencies', and cannot retrieve the package name string or version number
My ps1 looks like this:
$targetName = "otherPackagenName"
Write-Host "Trying to get version # of $targetName if it exists inside project.json"
# get json file contents
$json = Get-Content .\project.json | ConvertFrom-Json
# retrieve dependencies
$dependencies = $json.dependencies
Write-Host "dependencies = $dependencies"
# iterate through each dependency
foreach ($dep in $dependencies) {
Write-Host "dep = $dep"
# try to get dependency name (attempt1)
$depName1 = $dep[0]
Write-Host "depName1 = $depName1"
# try to get dependency name (attempt2)
$depName2 = $dep.Name
Write-Host "depName2 = $depName2"
if($depName1 -eq $targetName) {
write-host "Found it! now get version number"
} else {
write-host "Did not find our package"
}
}
output shows it correctly retrieves the json key/value pair, but I cant figure out how to retrieve the package name and version number, as every thing ive tried just returns blank:
Trying to get version # of otherPackagenName if it exists inside project.json
dependencies = #{AST.NxTestware.main=1.1.0; otherPackagenName=7.7.7}
dep = #{AST.NxTestware.main=1.1.0; otherPackagenName=7.7.7}
depName1 = #{AST.NxTestware.main=1.1.0; otherPackagenName=7.7.7}
depName2 =
Did not find our package
my dependencies is coming through like so:
#{AST.NxTestware.main=1.1.0; otherPackagenName=7.7.7}
How can I iterate through this object?
How can I retrieve the key ('AST.NxTestware.main') and value ('1.1.0') for each dependency?
I'm guessing you're looking for this:
$json.Dependencies | ForEach-Object {
$prop = $_.PSObject.Properties
[pscustomobject]#{
DependencyName = $prop.Name
Version = [version] $prop.Value
}
}
You can get an object's property Name and property Value by accessing the object's PSObject member, from there you can reference the Properties property of each object.

Azure pipelines -Add new element in json array VSTS pipelines (Appsettings.json)

Is this possible to add a new element in an array of appsetting.json in Azure Release Pipeline?
In appsetting.json I have array variable which I need to fill with another element during deployment through Azure Pipeline.
"Array": [
{
"Name": "AD1",
"IsDefault": "true",
"IdPEntityId": "URL1",
"Metadata": "XMLpath1"
},
{
"Name": "AD2",
"IsDefault": "false",
"IdPEntityId": "URL2",
"Metadata": "XMLPath2"
}
]
Here in the above JSON array I need to add another one elemental last position (array-Index:2).
[CmdletBinding()]
param(
[string] $AdName,
[bool] $AdIsDefault,
[string] $AdIdPEntityId,
[string] $AdMetadata,
[string] $AppSettingFilePath
)
clear-Host
Write-Host 'Updating appsettings.json...' -ForegroundColor Yellow
function Format-Json([Parameter(Mandatory, ValueFromPipeline)][String] $json) {
$indent = 0;
($json -Split '\n' |
% {
if ($_ -match '[\}\]]') {
# This line contains ] or }, decrement the indentation level
$indent--
}
$line = (' ' * $indent * 2) + $_.TrimStart().Replace(': ', ': ')
if ($_ -match '[\{\[]') {
# This line contains [ or {, increment the indentation level
$indent++
}
$line
}) -Join "`n"
}
$JsonDataAdd=#"
{
"Name":"$AdName",
"IsDefault": "$AdIsDefault",
"IdPEntityId":"$AdIdPEntityId",
"Metadata": "$AdMetadata"
}
"#
Write-Host ' Active directory details :' -ForegroundColor Yellow
Write-Host `n $JsonDataAdd -ForegroundColor Green
$jsonData = Get-Content "$AppSettingFilePath" | Out-String | ConvertFrom-Json -ErrorAction Stop
$jsonData.IdentitySettings.ExternalProviders.Saml2Providers += (ConvertFrom-Json $JsonDataAdd)
$jsonData | ConvertTo-Json -Depth 10 | Format-Json | Set-Content "$AppSettingFilePath" -Encoding UTF8
Write-Host 'Successfully Updated -appSettings.json !' -ForegroundColor Yellow
You could use JSON variable substitution. This feature substitutes values in the JSON configuration files. It overrides the values in the specified JSON configuration files (for example, appsettings.json) with the values matching names of release pipeline and stage variables.
When in "Deploy Azure App Service" release task you should see a "File Transforms and Variable Substitution" section. In here you will supply the path to the json file you want to swap variable values.
[![enter image description here][1]][1]
Then you just need to define the required substitution values in release pipeline or stage variables. From here you can add the json property you want to modify as a variable.
[![enter image description here][2]][2]
Finally after the transformation, the JSON will contain new. Azure DevOps will then swap out these values for you when deploying.
More details you could refer our official tutorial here: [File transforms and variable substitution reference][3]
Update:
It only works to adjust existing entries in the appsettings.json files, it doesn't seem to be able to add any new one. You could also take a look at the JSON variable substitution notes
Variable substitution is applied for only the JSON keys predefined in
the object hierarchy. It does not create new keys.
As a workaround, you could choose to use the File Creator extension:https://marketplace.visualstudio.com/items?itemName=eliostruyf.build-task to push the whole new appsettings.json file in the pipeline.
Update2
OP finally moved with PS script written by him to add new elements in Arrays of Appsettings.json

Extracting variables from calling the value- Getting Error message in condition

I am trying to do validation. checking the deployed values with the given values. I extract the vnet values from Azure resources using RestAPI method and convertto-json from Object because of vnet object is giving me empty object (#{value=System.Object[]}). The following is the Json code I am getting:
{
"value": [
{
"properties": "#{virtualNetworkSubnetId=/subscriptions/<XXXX>/resourceGroups/<XXXX>/providers/Microsoft.Network/virtualNetworks/<XXXX>/subnets/<XXXX>; ignoreMissingVnetServiceEndpoint=True; state=Ready}",
"id": "/subscriptions/<XXXX>/resourceGroups/<XXXX>/providers/Microsoft.DBforPostgreSQL/servers/<XXXX>/virtualNetworkRules/<XXXX>",
"name": "<XXXX>",
"type": "Microsoft.DBforPostgreSQL/servers/virtualNetworkRules"
}
]
}
The following powershell command is to compare the value but getting an error saying $vnet.name and $vnet.id is $null
$vnet= ( $vnet | ConvertTo-Json)
It "has this number of vNet Rules defined: $($config.vnetRules.count)"
{
$vnet.count | Should -Be $config.vnetRules.count
}
#$vnet.count is working and giving an success message
foreach ($vnetRule in $config.vNetRules) {
Write-Host $vnet #-> getting Json
Write-Host $vnet.Name #-> return as Empty($null)
Write-Host $vnet.value.Name #-> return as Empty($null)
Write-Host $vnet.id #-> return as Empty($null)
Write-Host $vnet.value.id #-> return as Empty($null)
it "has a vNet rule named: $($vnetRule.ruleName)" {
$vnet.name | Should -Be $vnetRule.ruleName
}
it "has a vNet Rule Subnet ID of: $($vNetRule.subnetId)" {
$vnet.value.id | Should -Be $vNetRule.subnetId
}
}
Returns $null.
In my attempt to recreate your invoke-restmethod output, I used your JSON packet as input to create the $vnet variable.
I believe the problem is you are using Write-host to display the object instead of simply the object name. Write-host will attempt to convert the complex object to a string and hence you see the weird output as you can see below. see the difference when i simply out the object?
Now, $vnet has 4 properties id, name, properties, type and can be invoked as shown.
In you case, you have converted the variable $vnet to json and then attempting to display its properties. But Json does not have any properties, except length. And hence, invoking those properties will give you null.

Problem to access Json data after ConvertFrom-Json in Powershell [duplicate]

This question already has answers here:
How can you use an object's property in a double-quoted string?
(5 answers)
Closed 4 years ago.
I have the following data structure in a config file:
{
"ProjectName" : "Test",
"Front" : {
"Credentials" : {
"Login" : "Administrator",
"Password" : "1234"
},
"RoleName" : "WebServer",
"TemplateName" : "WS2016",
"VHDSourcePath" : "D:\\VMs\\WS2016\\Virtual Hard Disks",
"VHDDesintationPath" : "D:\\VMs\\new",
"SwitchName" : "JoelSwitch"
}, ...
I use the following script to parse and use this config file:
$Specs = Get-Content -Raw -Path .\Specs.json | ConvertFrom-Json
$NewVmName = $Specs.ProjectName + "_" + "Front"
$TemplateName = $Specs.Front.TemplateName
$Source = $Specs.Front.VHDSourcePath
Write-Verbose "First we copy $Source\$TemplateName.vhdx into
$Specs.Front.VHDDesintationPath\$NewVmName.vhdx" -Verbose
When I access the json structure, it has a weird behavior: on the last command, I use a local variable to capture the Source, and I use the json structure directly for the destination.
Here is the output I get :
First we copy D:\VMs\WS2016\Virtual Hard Disks\WS2016.vhdx into #{ProjectName=CSF; Front=;Back=}.Front.VHDDesintationPath\CSF_Front.vhdx
you see that the source is correct compared to the config file, but the second parameter is like an object structure, not the value of destination property.
If I rewrite the script like this, it works:
$Source = $Specs.Front.VHDSourcePath
$Dest = $Specs.Front.VHDDesintationPath
Write-Verbose "First we copy $Source\$TemplateName.vhdx into $Dest\$NewVmName.vhdx" -Verbose
How come? Do i need to systematically capture properties in local variables? Why can't I use the structure directly?
Thanks !
This happens because how powershell interpreter reads what you give to it. basically a . isnt considered a part of the powershell variable. its considered a string character. hence it gives you back you variable and adds .Front.VHDDesintationPath to it. try this:
Write-Verbose "First we copy $Source\$TemplateName.vhdx into $($Specs.Front.VHDDesintationPath)\$NewVmName.vhdx" -Verbose

ReportService2010: create parent directories

I wrote a PowerShell script to bulk upload RDL files to SSRS 2014. I'm using the SOAP API exposed by ReportService2010.aspx:
$ssrsProxy = New-WebServiceProxy -Uri $uri -Credential $cred
$itemType = $ssrsProxy.GetItemType("/$reportFolder")
if($itemType -like "unknown")
{
$ssrsProxy.CreateFolder($reportFolder, "/", $null)
}
This works if $reportFolder is "foo", but not if it's "foo/bar". The error is:
Exception calling "CreateFolder" with "3" argument(s): "The name of the item 'foo/bar' is not valid. The name must be less than 260 characters long. The name must not start with a slash character or contain a reserved character. Other restrictions apply. For more information on valid item names, see http://go.microsoft.com/fwlink/?LinkId=301650.
The URL in the message is invalid and redirects to a "future resource" page. The actual documentation for CreateFolder says:
You can use the forward slash character (/) to separate items in the full path name of the folder, but you cannot use it at the end of the folder name.
Am I interpreting this incorrectly, or does it not actually work as documented?
My quick and dirty solution with no error handling. Use at your own risk.
$elements = $path.Split("/")
$parent = "/"
foreach($element in $elements)
{
$name = ""
if($parent.EndsWith("/"))
{
$name = "$parent$element"
}
else
{
$name = "$parent/$element"
}
$type = $ssrsProxy.GetItemType($name);
if($type -like "unknown")
{
$ssrsProxy.CreateFolder($element, $parent, $null)
}
$parent = $name
}