I am trying to create a variable of true/false within a function and then use that variable later in the script. My current function has a return which works, but i can not seem to understand how to return or create new object to pass multiple variables.
As the script works now, the function is called with a parameter of a tag name which calls an API call that retrieves JSON file and then parses through that file and performs a few steps. When I call the function I want it to return the HTML table as well as a true or false variable if the $values from the json contain anything below 1.
function Request-API {
[CmdletBinding()]
[OutputType([psobject])]
param (
$tagName
)
Invoke-WebRequest -Uri "***removed for company privacy*** -Headers $headers -OutFile $DataExplorerJson
#Store API results as variable
$json = Get-Content $DataExplorerJson -Raw | ConvertFrom-Json
#Check values and set $subjectCheck to TRUE if there are failures
$values = @($json.result.data.values)
foreach ($i in $values) {
if ($i -lt 1) {
$subjectCheck = $true
}
}
Write-Output "SubjectCheck "$subjectCheck
###Create $report object of containing table data
## Retrives value status from JSON. If greater than 1 sets to PASS
$condition = '1'
try {
$report = $json.result.data | ForEach-Object {
$status = 'FAIL'
if ($_.values[0] -ge $condition) {
$status = 'PASS'
}
#Adds synthetic monitor names and $values to object
[pscustomobject]@{
Application = $_.dimensionmap.PSObject.Properties.Match('*.name').Value
Status = $status
}
}
}
catch {
## Write-Output 'No failures occured'
}
#Convert report to HTML and add XML
[xml]$fullTable = $report | Select-Object Application, Status | ConvertTo-Html -Fragment
##Set color for PASS & FAIL stastuses
try {
$fullTable.SelectNodes("/table/tr/td[text()='PASS']").SetAttribute('class', 'pass')
$fullTable.SelectNodes("/table/tr/td[text()='FAIL']").SetAttribute('class', 'fail')
}
catch {
## Write-Output 'No failures occured'
}
return $fullTable
}
## Call function with $tag param
$medicalReview = 'Medical%20Review~'
$priorAuth = 'Prior%20Auth~'
$medicalReviewTable = Request-API $medicalReview
$subjectMR = $subjectCheck
Write-Host "subject check subjectMR: "$subjectMR
$priorAuthTable = Request-API $priorAuth
$subjectPA = $subjectCheck
Write-Host "subject check subjectPA: "$subjectPA
if($subjectMR -eq $true -or $subjectPA -eq $true) {
$subject = 'Dynatrace Synthetic On Demand Monitoring Report - FAIL'
} else {
$subject = 'Dynatrace Synthetic On Demand Monitoring Report - PASS'
}
The code starting with "#Check values and set $subjectCheck" is where the issue is. I know the $subjectCheck is not passing the variable.
I have also tried:
$values = @($json.result.data.values)
foreach ($i in $values) {
if ($i -lt 1) {
$subjectCheck = New-Object -Property $true -TypeName psobject
}
}
Write-Output "SubjectCheck "$subjectCheck
I do not think I am fully understanding functions, but after so much reading I truly don't know how to handle this.
One way to do it is to just send both objects to the output stream from the function, which effectively returns an array of values:
function Get-TwoResults
{
write-output "one"
write-output "two"
}
$results = Get-TwoResults
$results[0] # displays "one"
$results[1] # displays "two"
You can also "unpack" the items in the return array into multiple variables like this:
$first, $second = Get-TwoResults
$first # displays "one"
$second # displays "two"
See Assigning Multiple Vvariables for more details.
Another option is to bundle the values into properties of a custom object:
function Get-CustomObject
{
write-output [pscustomobject] @{
"First" = "one"
"Second" = "two"
}
}
$object = Get-CustomObject
$object
# displays:
#
# Name Value
# ---- -----
# First one
# Second two
and you can access the properties like this:
$object.First # displays "one"
$object.Second # displays "two"
Note that you don't specifically need to put the command name write-output
in the above code samples - any uncaptured expression results are implicitly returned to the output stream as if you'd called write-output
.
The two samples below work just as well as the ones above:
function Get-TwoResults
{
"one"
"two"
}
function Get-CustomObject
{
[pscustomobject] @{
"First" = "one"
"Second" = "two"
}
}
Note also that return $x
is functionally equivalent to write-output $x; return
.