I am trying to define a variable globally in powershell and get the value in one function and pass that value in different function but I am unable to do so. I googled and tried $global:myvariable but its not working. what wrong am i doing?
here is my code:
$global:namerel = $null
Function GET-value{
$uriAccount = $orz + "_apis/release/releases/1914?api-version=6.0"
$responseRels = Invoke-RestMethod -Uri $uriAccount -Method get -Headers $AzureDevOpsAuthenicationHeader
$namerel = $responseRels.Name
write-host $namerel # it prints the required value
}
Function GET-rel{
$test = GET-value
write-host $namerel # nothing gets printed. its blank
}
To use a variable scoped global, you need to use syntax $global:namerel inside the functions. Without that, variable $namerel will be just a new variable, local to that function.
Also, you may not need to use global. Scope script usually is broad enough. See About_scopes
Related
Below is a snip of my powershell code where my response or my variable($witrevisions) is of type array. I am looking to bind this in a html tag which i have defined in the power shell. As I am very new to coding stuff , I am looking the ways how can I bind array to html tag in best possible way
...continuing my line of code
$response4s = (Invoke-RestMethod -Uri $uriAccount -Method get -Headers $AzureDevOpsAuthenicationHeader).values
$wits = $response4s | where({$_.fields.'System.WorkItemType' -eq 'Task'}) # Only retrieve Tasks
$witrevisions = #()
foreach($wit in $response4s){
$customObject = new-object PSObject -property #{
"Title" = $wit.fields.'System.Title'
"AssignedTo" = $wit.fields.'System.AssignedTo'
}
$witrevisions += $customObject
}
$witrevisions | Select-Object `
Title,
AssignedTo
}
and this the sample response i am getting in $witrevisions which i have exported in text file. its a table with two column one having emails and other having a title name.i have tried to show by giving it a table view for better understanding
Assigned To Title
xyz#outlook.com testingpro
drdr#outlook.com resttesting
and here is the html tag where I trying to bind the $witrevisions.
$DOWNLOAD_PAGE_BODY_CONTENT = "<!DOCTYPE html>
`n<html>
`n<head>
`n <title>Validation</title>
`n</head>
`n<body>
`n
`n<p>Please click the link to download the release.</p>
`n<p></p>
`n<p></p>
`n<p>$witrevisions</p>
`n</body>
`n</html>
`n"
Can someone please tell me how should I do this??
Here is an example of some code that would take your array and emit a table, with an explanation to help you tweak to your specific needs:
"<table><body>$($witrevisions|% {"<tr><td>$($_.Title)</td><td>$($_.AssignedTo)</td></tr>"} )</body></table>"
The double quotes are important because they allow string interpolation (it will replace variables with this value, versus being read a plain text. E.g. '[' + $test + ']' => "[$test]"
If you need to do more complex logic in string interpolation, you can use $(...), the ellipses being regular code.
You can iterate through an array by piping to the ForEach-Object, or it's alias %. All the code in the braces will be executed for each item in the array. The current items is represented by $_.
We're then back to string interpolation and using $(...), which is needed to access the members of the current item.
Note: There are several other ways to accomplish (functionally) the same thing. E.g. foreach(...){} vs |%{...}, so feel free to use a different technique if you are more comfortable with doing something a different way.
Over the past few days I've been looking for documentation on variable expansion in JSON objects. I've tried a lot of recommendations and fixes, but none of them seem to work quite as expected. I'm left wondering if there's a better way than I have implemented. Anyway, on to my use case.
Use Case
I have an array of integers, which represent objects in a web application. These objects are able to have a relationship established between them by making a POST request to an API endpoint.
This array of integers is referred to as $combined.
PS C:\> $combined
i_id m_id
------------ ----------
75419 6403
75420 6403
75421 6403
75410 6403
To set up the parameters used for my POST request, I've created another array called $associationParams.
$associationParams = #{
ContentType = "application/json"
Body = '{"id": '+$($thing).m_id+'}'
Method = "POST"
URI = "https://application/api/in/$($thing.i_id)/endpoint"
Headers = $headers
}
The $headers variable above is the authorization token.
So, my initial inclination is to loop through the array of integers ($combined) and call Invoke-RestMethod as so:
Foreach ($thing in $combined) {
Invoke-RestMethod #iocAssociationParams
}
Problem
So, I don't really have a problem per se... There seems to be some inconsistency in my testing where the final ForEach doesn't seem to loop through all the elements in the $combined array... But I am wondering if there's a better way. I've tried string formatting the JSON object in the Body parameter in $associationParams, but it definitely didn't work. I've also tried various forms of quoting, but they didn't work either. Is trying to splat the parameters for Invoke-RestMethod the best way? Should I just list out all the parameters for Invoke-RestMethod in the ForEach loop?
Use the -f format operator to insert $thing.m_id inside the foreach into $AssociationParams.
You have to escape the literal curly braces by doubling them.
Foreach ($thing in $combined) {
$AssociationParams = #{
ContentType = "application/json"
Body = '{{"id": {0}}}' -f $thing.m_id
Method = "POST"
URI = "https://application/api/in/$($thing.i_id)/endpoint"
Headers = $headers
}
Invoke-RestMethod #AssociationParams
}
Here's my solution as implemented.
Foreach ($thing in $combined) {
# Now we create the body of the request as a Powershell object with the intent to convert it to JSON later
$AssociationBodyObj = [PSCustomObject]#{
id = $($thing.id)
}
# ...and then we convert it to JSON
$AssociationBodyObj = $AssociationBodyObj | ConvertTo-Json
$iocAssociationParams = #{
ContentType = "application/json"
Body = $AssociationBodyObj
Method = "POST"
URI = "https://application/api/in/$($thing.i_id)/endpoint"
Headers = $headers
}
Invoke-RestMethod #AssociationParams
}
I'm trying to concatenate a variable reference inside another string but it keeps showing wrong values.
Basically I intend to update variable $arq value acording to variable $version, without having to reset $arq.
I'm using [ref] but not sure it's the best way to do so.
I've tryed the following so far.
$downloadSource = "\\domain.or.ip\folder"
$version = "0.0.0"
$arq = "file_name_$([ref]$version)`_filename_continuation.zip"
function UpdateVersion {
(Get-ChildItem -name "$downloadSource\file_name*").Split('_')[2]
}
$version = UpdateVersion
echo $version
echo $arq
Variable $version is being updated correctly.
But $arq is receiving the wrong value:
"file_name_System.Management.Automation.PSReference`1[System.String]_filename_continuation.zip"
I tried changing $arq as follows
$arq = "file_name_" + $(($versaoEsperada).value) + "`_filename_continuation.zip"
But the same wrong value is shown.
Would you guys help me, please?
Thanks
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
I am running a GUI that takes user input but can be changed before finalizing if they make a mistake. When the form opens, I am trying to initialize the globals to null. This is failing. I put a breakpoint on the code and looked at the value before and then stepped into it. The value does not change.
So for example, if I run the form and enter "Foo" as my global variable, exit the form, then run the form again, even after the line in question executes, the value of the global is still "Foo". What is going on? I have used this exact code with other GUIs and it never failed (but the values were generated automatically rather than based on user input).
# Define and initialize global variables
$global:ServerName = $null # <-- This fails to reset the variable from the previous run of the form
function ValidateChoices(){
$OKToGo = $true
$TempServerName = $null
try {
# Only Allow Valid NETBios Name with AlphaNumberic and - up to 15 characters
[ValidatePattern("^[A-Za-z\d-]{1,15}$")]$TempServerName = $ServerNameTextbox.Text
$ServerNameTitle.BackColor = ""
$ServerNameTextbox.BackColor = ""
$global:ServerName = $TempServerName
} catch {
$OKToGo = $false
$ServerNameTitle.BackColor = "Pink"
$ServerNameTextbox.BackColor = "Pink"
}
...
if ( $OKToGo ){
"ServerName=" + $global:ServerName | Out-File c:\debug.txt
}
}
Here is the answer: When ValidatePattern is run against a variable, those restrictions are kept and re-evaluated anytime an attempt to change the variable is made. This holds true even if ValidatePattern was not explicitly called. And because it was a global variable, those restrictions rode through multiple iterations of the form. Because $null does not conform to my listed ValidatePattern parameters, the call to change the value was ignored