I then changed the line so that the command was assigned to a variable, so that I could test the validity of the variable before displaying it in the console window:
When I run the code in the PowerShell ISE, the output is correctly displayed on multiple lines. However when I run the code in a PowerShell console, it displays like this:
Well to be fair you donât show how you retrieve the variable value. You could be sticking it in a form for all we know. It was a good guess as it does look like it was forced into a single string. Please share how you are outputting the stored variable.
I paused the script again at the same point (using a breakpoint), and checked the value of the variable $x from the ISE command line:
[DBG]: PS C:\Users\Julian\Documents\WindowsPowerShell\Scripts> $x
Address Port Type
------- ---- ----
172.20.80.80 3260 Static
172.20.80.81 3260 Static
As you can see, the output from the script does NOT match the variable value???
The variable is an object, obviously, so whatâs going on here?
I donât understand why the script runs and each iteration of the loop produces a different output.
Looks like Output-Object correctly outputs the object $x as its value is formatted, and by assigning it to a string variable, I can ouput the variable, using Write-Host, in colour!
Note:
$x is type System.Array
$Output is type System.String
What method of outputting $x would you use? You canât just put $x on a line by itself within the script as that is not recognised as the name of any cmdlets. It has to be output using a PowerShell method.
That is incorrect. But the question is too vague. If I really just wanted it to output itâs default just like the first command, then yes, just drop $x and let powershells implicit output handle it or donât store it in a variable at all.
Run each of these independently. Note that even though $x isnât surrounded by quotes in the 4th example, Write-Host always converts the input to string.
# The following 2 examples will have the same "object" output dictated by its own default formatting rules
foreach($esx in $esxhosts){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
}
}
foreach($esx in $esxhosts){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
$x
}
}
# these two will be the same incorrectly stringigified versions
foreach($esx in $esxhosts){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
"$x"
}
}
foreach($esx in $esxhosts){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
Write-Host $x
}
}
What youâre seeing in the first example is the default member (property) set. Itâs output nice for your eyes by the powershell formatting system based on the cmdlets own format specification. Now a lot of cmdlets will make the ToString() method actually output the same or something just as nice for human consumption. However some, like this IscsiHBA cmdlet, doesnât offer anything special for ToString() so powershell gets garbage when it asks it to âstringifyâ itself.
Now for what you see on the screen, if you want to capture the text exactly like that and donât care about object, just Out-String it. Check these examples.
# Get-Member on the default, easy on the eyes output.
foreach($esx in $esxhosts | Select-Object -First 1){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
$x # implicit output so you can see it's formatted the way you like
$x | Get-Member
}
}
# Now we'll show the same output but this time it's been turned into pretty, but hard to work with down the pipeline, string
foreach($esx in $esxhosts | Select-Object -First 1){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "=========================================="
Write-Host "iSCSI Targets on $esx"
Write-Host "=========================================="
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
$x | Out-String
$x | Out-String | Get-Member
}
}
So even though both show the same output on the screen, one is still an object and the other is not. Now if someone made the cmdletâs ToString() method do that, itâd be a lot easier to use in double quotes or Write-Host.
So it really comes down to what you are trying to do with the output. Are you wanting to both show it to use and capture the object? Perhaps just do both, because the -Host cmdlets arenât sent on stdout so it wonât be captured (without trying hard to do so) while the object does, try it yourself!
# Pretty output for the eys and only the objects are collected in $result.
$result = foreach($esx in $esxhosts){
$hba = $esx | Get-VMHostHba -Type iScsi
if ($hba){
Write-Host "==========================================" -ForegroundColor DarkCyan
Write-Host "iSCSI Targets on $esx" -ForegroundColor Gray
Write-Host "==========================================" -ForegroundColor DarkCyan
# Get-IScsiHbaTarget -IScsiHba $hba -Type Send | Sort Address
$x = Get-IScsiHbaTarget -IScsiHba $hba | Sort Address
Write-Host ($x | Out-String) -ForegroundColor Cyan
$x
}
}