How to prevent Powershell not showing script processing data - powershell

I have created a powershell script for updating SharePoint List. When i run it shows all the backend processing to the console for example all the list schema info. I want it only show script created Out put (The only output with Write-Host) and not out of the box backend processing. Is there any command available to prevent that?
it shows counting like below when I use .add method of ArrayList where ever in script
0
1
2
3
and it shows List XML Schema when i store List items in some variable in the script like below:
Sealed : False
Version : 28
DisplayFormTemplateName : DocumentLibraryForm
EditFormTemplateName : DocumentLibraryForm
NewFormTemplateName : DocumentLibraryForm
NewFormUrl :
MobileNewFormUrl :
EditFormUrl :
MobileEditFormUrl :
DisplayFormUrl :
MobileDisplayFormUrl :
Id : 0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39009893A4DD0A05487AAE05EAE8D183333C003933922476541344B8A065CBACE8178D
ReadOnly : False
Name : NewsPage
NameResource : Microsoft.SharePoint.SPUserResource
FeatureId : 00000000-0000-0000-0000-000000000000
Description : Used to create news articles.
JSLink :
DescriptionResource : Microsoft.SharePoint.SPUserResource
Hidden : False

Some .Net Methods and external programs output their exit code and other output to stdout.
You can either add the void keyword to the arraylist "Add" command or pipe it to Out-Null
$MyList = [System.Collections.ArrayList]#()
1..10 | % { $MyList.Add($_) } # outputs 0 to 9
1..10 | % { [void]$MyList.Add($_) } # no output
1..10 | % { $MyList.Add($_) | Out-Null } # no output

Related

PowerShell - extracting nested object

I am fairly new to PowerShell and am trying to use a module called PoshWAPI. This module is used to query Infoblox. One of the commands is Get-IBobject which allows me to query infoblox for a record type.
This is my code so far:
Set-IBConfig -ProfileName 'MyGrid' -WAPIHost dns.example.com -WAPIVersion latest -Credential (Get-Credential) -SkipCertificateCheck
$result = Get-IBObject -ObjectType record:host 'name=host1.network.example.com' -ReturnAll
That works well and returns the following
_ref : record:host/ZG5zLmhvc3QkLl9kZWZhdWx0LnRtY3MuaW5mb3NlYy5zMGE0OTFlMDAtMjMudDkwNC5zb25lc3N1czAx:host1.network.example.com/default
allow_telnet : False
comment : TOSD-37248
configure_for_dns : True
ddns_protected : False
disable : False
disable_discovery : False
dns_name : host1.network.example.com
extattrs :
ipv4addrs :{#{_ref=record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudG1jcy5pbmZvc2VjLnMwYTQ5MWUwMC0yMy50OTA0LnNvbmVzc3VzMDEuMTAuNzMuMzAuMTYu:10.73.30.16/host1.network.example.com/default;
configure_for_dhcp=False; host=host1.network.example.com; ipv4addr=10.73.30.16}}
name : host1.network.example.com
network_view : default
rrset_order : cyclic
use_cli_credentials : False
use_snmp3_credential : False
use_snmp_credential : False
use_ttl : False
view : default
zone : network.example.com
The info I actually require from there are the name field and within the ipv4addrs field is a field called ipv4addr.
Currently I export it all to CSV using this command
$result | Export-Csv -Path C:\Users\neil.bloyce\Documents\2023\2.Feb\InfoBlox.csv
It isn't elegant but gets some of the info I want, however within the ipv4addrs I don't get any info except for System.Object[].
How do I adjust my code so that I can pull the ipv4addr out of ipv4addrs so I can see it in the CSV, Ideally the only info I actually need is dns_name and ipv4addr.
I am not sure how I attach the CSV file.
Kind regards
Use the Select-Object cmdlet to copy and transform only a subset of the properties from the object:
$result |Select-Object Name,#{Name='Addresses';Expression={ $_.ipv4addrs.ipv4addr -join ', ' }} |Export-Csv -Path C:\Users\neil.bloyce\Documents\2023\2.Feb\InfoBlox.csv -NoTypeInformation
Here, we extract the Name property from the original object, and then create a new calculated property that extracts the nested ipv4addr values and joins them together in a single string (thus causing Export-Csv to render the value correctly).

ConvertFrom-Json is giving System.Object[] for some sections in Powershell

I am very new to Windows PowerShell. I am trying to fire ConvertFrom-Json command for the below Json :-
$ret=[{"ID":"ABC","type":"Test","code":"AD","enabled":true,"sourceMappings":[{"source":"Test","values":[{"code":"AD","value":"Anderson","enabled":true,"canonicalValue":true,"downStreamDefaultValue":true}]}],"startDate":0,"endDate":0,"updatedBy":"YY","updateDate":1590085877449,"version":4}]
and I am getting below output :-
ID : ABC
type : Test
code : AD
enabled : True
sourceMappings : {#{source=Test; values=System.Object[]}}
startDate : 0
endDate : 0
updatedBy : YY
updateDate : 1590085877449
version : 4
If you notice the values been assigned to System.Object[].Please help me how to get the original values in the output.
I think the converting is all fine.
You can access the values via:
$tmp = $ret | ConvertFrom-Json
$tmp.sourcemappings
$tmp.sourcemappings.values.code
and so on
Lets first make your json file more readable:
{
"ID":"ABC",
"type":"Test",
"code":"AD",
"enabled":true,
"sourceMappings":[{"source":"Test","values":[{"code":"AD","value":"Anderson","enabled":true,"canonicalValue":true,"downStreamDefaultValue":true}]}],
"startDate":0,
"endDate":0,
"updatedBy":"YY",
"updateDate":1590085877449,
"version":4
}
Second of all, your way of defining json variable is incorrect. In powershell, you need to define json variables is surrounding the json content with #" and "#. The correct way to set $ret equal to your json file would be like this:
$ret=#"
{
"ID":"ABC",
"type":"Test",
"code":"AD",
"enabled":true,
"sourceMappings":[{"source":"Test","values":[{"code":"AD","value":"Anderson","enabled":true,"canonicalValue":true,"downStreamDefaultValue":true}]}],
"startDate":0,
"endDate":0,
"updatedBy":"YY",
"updateDate":1590085877449,
"version":4
}
"#
Where $ret would be considered a string data type. You could then convert the json with:
$var = ConvertFrom-Json -InputObject $ret
Where you could now interact with it like normal. For example, $var.ID would output ABC and if you tried checking the object type again with $var.gettype() it would output:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
Where the type would be a PSCustomObject
Update: It seems as if I misunderstood the question, my bad!
The reason it says
sourceMappings : {#{source=Test; values=System.Object[]}}
Is because powershell doesn't want to display the whole value since there are many components in the value. You can view the values in the sourceMappings class with $var.sourceMappings where the output would be:
source values
------ ------
Test {#{code=AD; value=Anderson; enabled=True; canonicalValue=True; downStreamDefaultValue=True}}
and you can keep on viewing deeper if you add on like $var.sourceMappings.code etc. etc.

PowerShell Job.Progress contains multiple objects

I am currently developing a backup manager for Hyper-V using PowerShell.
I ran into problems when starting an export job like this:
$job = (export-vm -name "Windows 10" -path F:\VM_Backup\ -asjob)
Now when querying the progress of the job I realized that two objects are inside my Progress property:
> $job.progress
ActivityId : 0
ParentActivityId : -1
Activity : Export wird ausgeführt
StatusDescription : Gelöscht
CurrentOperation :
PercentComplete : 1
SecondsRemaining : -1
RecordType : Processing
ActivityId : 0
ParentActivityId : -1
Activity : Export wird ausgeführt
StatusDescription : Gelöscht
CurrentOperation :
PercentComplete : 37
SecondsRemaining : -1
RecordType : Processing
While the second progress update makes real progress (increasing percentage), the first one always stays like above.
I have never seen this behavior before and that really doesn't make any sense to me. How do I (programmatically) select the "right" job?
By design, the .Progress property collects all progress messages written by the job - it doesn't just reflect the latest status.
The most recently written message is the last one added to the .Progress collection, so you can use index [-1] to retrieve it.
$job.Progress[-1]
Note: For Start-Job-created jobs, you must access the .Progress property on the (one and only) child job instead: $job.ChildJobs[0].Progress[-1] - see about_Job_Details.

Trouble comparing JSON (or custom PS) objects

I am having trouble with object comparison.
I have an application which spits out JSON data. Each time I run my script, I will get the current values and import the stored values from the previous run (either from a .json or .xml file). At the end of the script, I will overwrite the stored values with the current values. The data looks like this:
Stored values:
id : 6549888
description : Windows CPU via WMI
name : Test
dataPoints : {#{id=6314; dataSourceId=6549888; name=CPUBusyPercent; description=%
of Busy CPU; alertTransitionInterval=8; alertClearTransitionInterval=0; type=2; dataType=2;
maxDigits=4; postProcessorMethod=expression;
postProcessorParam=100-(PercentProcessorTime/100000); rawDataFieldName=; maxValue=; minValue=0;
userParam1=; userParam2=; userParam3=; alertForNoData=3; alertExpr=>= 50 60 70; alertSubject=CPU
alert on ##HOST##; alertBody=The host ##HOST## is in state ##LEVEL##. CPU is ##VALUE## percent
busy - it has been in this state since ##START##, or for ##DURATION##}}
Current values:
id : 6549888
description : Windows CPU via WMI
name : Test
dataPoints : {#{id=6314; dataSourceId=6549888; name=CPUBusyPercent; description=%
of Busy CPU; alertTransitionInterval=8; alertClearTransitionInterval=0; type=2; dataType=2;
maxDigits=4; postProcessorMethod=expression;
postProcessorParam=100-(PercentProcessorTime/100000); rawDataFieldName=; maxValue=; minValue=0;
userParam1=; userParam2=; userParam3=; alertForNoData=3; alertExpr=>= 90 95 98; alertSubject=CPU
alert on ##HOST##; alertBody=The host ##HOST## is in state ##LEVEL##. CPU is ##VALUE## percent
busy - it has been in this state since ##START##, or for ##DURATION##}}
In this example, someone changed the alertExpr from "50 60 70" to "90 95 98" and I need to catch that (along with changes made to the rest of the properties).
When I run a foreach loop, I am not getting back any differences, but when I look at a single property, Powershell does report the difference. So the following returns nothing:
foreach ($dataSource in $currentDataSources) {
foreach ($recordedDatasource in $previousDataSources) {
If ($dataSource.id -eq $recordedDatasource.id) {
Compare-Object $dataSource $recordedDatasource
}
}
}
But looking at the index 1034 (that's my test item) does show a difference:
Compare-Object $currentDataSources[1034].datapoints.alertexpr $previousDatasources[1034].datapoints.alertexpr
What is the best way to check each of the properties between my to sets of data?
Thanks.

Powershell command $table.Columns.Add("NewFieldName") results in unexpected output to console

The following PowerShell script results in unexpected, and in my case unwanted, output to the console:
$table = New-Object System.Data.DataTable
$table.Columns.Add("NewFieldName")
Unexpected output:
AllowDBNull : True
AutoIncrement : False
AutoIncrementSeed : 0
AutoIncrementStep : 1
Caption : NewFieldName
ColumnName : NewFieldName
Prefix :
DataType : System.String
DateTimeMode : UnspecifiedLocal
DefaultValue :
Expression :
ExtendedProperties : {}
MaxLength : -1
Namespace :
Ordinal : 0
ReadOnly : False
Table : {}
Unique : False
ColumnMapping : Element
Site :
Container :
DesignMode : False
Expected output:
 
My questions are:
Why?
How can I prevent this output from going out to the console with the rest of my output?
TLDR: Add [void] like this
[void]$table.Columns.Add("NewFieldName")
Why? Because PowerShell tends to output the command's return value/object to the console (or whatever is receiving the output) by default.
How can I prevent this output from going out to the console with the rest of my output? Thank you to #PetSerAl for pointing out the solution of adding [void] to the left of the command. This casts the command's return type to a [void] which will not output to the console.
After #PetSerAl pointed me in the right direction I found these pages that helped clear things up:
Into the [void]
Gotcha #10 in PowerShell Gotchas