Powershell returns wrong output - powershell

I have simplified the process so that anyone can reproduce it (in my script it is a problem within a workflow, no functions involved, therefore I can`t save these values in variables and then show them by console). The first thing is to use powershell ISE.
function AAA {
$datum1 = New-Object -TypeName PSObject
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnB -Value "BB"
return $datum1
}
function BBB {
$datum2 = New-Object -TypeName PSObject
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnC -Value "CC"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnD -Value "DD"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnE -Value "EE"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnF -Value "FF"
return $datum2
}
AAA
BBB
Output:
ColumnA ColumnB
------- -------
AA BB
AA
Any idea why this happens?
EDIT:
I have solved this "sh1t" in the following way
function AAA {
$datum1 = New-Object -TypeName PSObject
$datum1 | Add-Member -MemberType NoteProperty -Name Index -Value "1"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnB -Value "BB"
$datum1
}
function BBB {
$datum2 = New-Object -TypeName PSObject
$datum2 | Add-Member -MemberType NoteProperty -Name Index -Value "2"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnC -Value "CC"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnD -Value "DD"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnE -Value "EE"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnF -Value "FF"
$datum2
}
AAA |? {$_.Index -eq "1"} | FT
BBB |? {$_.Index -eq "2"} | FT
Anyway, can someone explain what's going on? I would really like to understand the reason and look for related information
EDIT2: Reply to Palle Due,
it doesn't work at all for my scenario as it adds a bit more complexity.
Out-Host is not an option. Example provided:
workflow Get-Report
{
param ([string[]]$computername)
foreach -Parallel ($computer in $computername) {
sequence {
InlineScript {
$AAA = Invoke-Command -ScriptBlock {
$datum1 = New-Object -TypeName PSObject
$datum1 | Add-Member -MemberType NoteProperty -Name Index -Value "1"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnB -Value "BB"
return $datum1
}
$AAA | Out-Host
$BBB = Invoke-Command -ScriptBlock {
$datum2 = New-Object -TypeName PSObject
$datum2 | Add-Member -MemberType NoteProperty -Name Index -Value "2"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnC -Value "CC"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnD -Value "DD"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnE -Value "EE"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnF -Value "FF"
return $datum2
}
$BBB | Out-Host
} #endinlinescript
} #endsequence
} #endforeach
} #endWF
$results = #()
$results = Get-Report -Verbose -Computer "localhost","localhost"
$results | FT

The easy fix is to pipe the output to Out-Host:
function AAA {
$datum1 = New-Object -TypeName PSObject
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum1 | Add-Member -MemberType NoteProperty -Name ColumnB -Value "BB"
return $datum1
}
function BBB {
$datum2 = New-Object -TypeName PSObject
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnA -Value "AA"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnC -Value "CC"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnD -Value "DD"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnE -Value "EE"
$datum2 | Add-Member -MemberType NoteProperty -Name ColumnF -Value "FF"
return $datum2
}
AAA | Out-Host
BBB | Out-Host
gives the output:
ColumnA ColumnB
------- -------
AA BB
ColumnA : AA
ColumnC : CC
ColumnD : DD
ColumnE : EE
ColumnF : FF
The thing is that powershell likes to output custom objects with four members or less horizontally. With five or more members they are output vertically. And then some strange neatness priciple kicks in: If you output multiple objects in a row, powershell will try to keep the same format. So if you started out horizontally, it will keep going horizontally and only output members with the same name as the first custom object. If you start out vertically it will keep going vertically and output all names.
That's why if you go:
BBB
AAA
you will get
ColumnA : AA
ColumnC : CC
ColumnD : DD
ColumnE : EE
ColumnF : FF
ColumnA : AA
ColumnB : BB
instead.
I haven't been able to find any documentation for this. They're just my own observations.

Related

Questions about Powershell objects, property names, multiple property values with the same name and dot sourcing issues

There is code at the bottom of this to help make it easy to reproduce what I'm asking in my questions. My questions are:
$parentObject.Children.Children.Andrew."Birthday Info" --- is there a programmatic way to know to need quotes and add quotes?"
$parentObject.Children.Robert.Children.Peter."Favorite Foods" --- I understand it creates a property name conflict if I try to add "Name" with a different value more than once, how can I add "Name" with a different food value multiple times? Should it be an array that I keep adding to and replacing/updating?
$parentObject."01/01/1960". --- why can't I dot source the child properties
$parentObject.Children.Robert. --- why can't I dot source the child properties, the 3rd level seems to be the limit?
$parentObject.01/01/1960; --- fails, returns a "0"
$parentObject."01/01/1960"; --- returns property names "Location"
and "Years Together"
$parentObject.{01/01/1960}; --- returns
property names "Location" and "Years Together"
$parentObject."01/01/1960". --- does not dot source
$parentObject.{01/01/1960}. --- does not dot source
$parentObject."01/01/1960".Location; --- returns property value
"Hawaii"
$parentObject.{01/01/1960}.Location; --- returns property
value "Hawaii"
$parentObject."01/01/1960"."Years Together"; --- returns property value "72"
$parentObject.{01/01/1960}.{Years Together}; --- returns property value "72"
$parentObject.anniversary - 01/01/1960; --- fails, performs a math
equation
$parentObject."anniversary - 01/01/1960"; --- returns
property values "Hawaii" and "62"
$parentObject.{anniversary - 01/01/1960}; --- returns property values "Hawaii" and "62"
$parentObject."anniversary - 01/01/1960". --- does not dot source
$parentObject.{anniversary - 01/01/1960}. --- does not dot source
Full code:
#Region Instantiate
$foodsObject = New-Object -TypeName psobject;
$birthDayObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$grandChildObject = New-Object -TypeName psobject;
$childObject = New-Object -TypeName psobject;
$parentObject = New-Object -TypeName psobject;
$anniversaryObject = New-Object -TypeName psobject;
#EndRegion /Instantiate
#Region Peter
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "22";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/2000";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Spaghetti" -Value "Spaghetti";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Pizza" -Value "Pizza";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Ice cream" -Value "Ice cream";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Red";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$grandChildObject | Add-Member -MemberType NoteProperty -Name "Peter" -Value $personalInformationObject;
#EndRegion /Peter
#Region Andrew
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "20";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/2002";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Big Mac" -Value "Big Mac";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Soup" -Value "Soup";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Cheese cake" -Value "Cheese cake";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Green";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$grandChildObject | Add-Member -MemberType NoteProperty -Name "Andrew" -Value $personalInformationObject;
#EndRegion /Andrew
#Region Robert
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "47";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/1975";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Burger King" -Value "Burger King";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Cheese Pizza" -Value "Cheese Pizza";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Beer" -Value "Beer";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Maroon";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Children" -Value $grandChildObject;
$childObject | Add-Member -MemberType NoteProperty -Name "Robert" -Value $personalInformationObject;
#EndRegion /Robert
$grandChildObject = New-Object psobject;
#Region Lisa
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "25";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/1997";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Burgers" -Value "Burgers";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Rice" -Value "Rice";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Cherry snowball" -Value "Cherry snowball";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Purple";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$grandChildObject | Add-Member -MemberType NoteProperty -Name "Lisa" -Value $personalInformationObject;
#EndRegion /Lisa
#Region Thomas
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "44";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/1978";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Chicken" -Value "Chicken";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Pit beef" -Value "Pit beef";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Coke float" -Value "Coke float";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Yellow";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Children" -Value $grandChildObject;
$childObject | Add-Member -MemberType NoteProperty -Name "Thomas" -Value $personalInformationObject;
#EndRegion /Thomas
#Region Jason and Pamela
#Region Jason
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "80";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/1942";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Grits" -Value "Grits";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Burgers" -Value "Burgers";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Malt drink" -Value "Malt drink";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Brown";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "Jason" -Value $personalInformationObject;
#EndRegion /Jason
#Region Pamela
$numberOfBirthdaysObject = New-Object -TypeName psobject;
$numberOfBirthdaysObject | Add-Member -MemberType NoteProperty -Name "Count" -Value "78";
$birthDateObject = New-Object -TypeName psobject;
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Date" -Value "01/01/1944";
$birthDateObject | Add-Member -MemberType NoteProperty -Name "Birthday Count" -Value $numberOfBirthdaysObject;
$birthDayObject = New-Object -TypeName psobject;
$birthDayObject | Add-Member -MemberType NoteProperty -Name "Birthday Info" -Value $birthDateObject;
$foodsObject = New-Object -TypeName psobject;
$foodsObject | Add-Member -MemberType NoteProperty -Name "Rice" -Value "Rice";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Cheese" -Value "Cheese";
$foodsObject | Add-Member -MemberType NoteProperty -Name "Popsicle" -Value "Popsicle";
$personalInformationObject = New-Object -TypeName psobject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Birthday" -Value $birthDayObject;
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Color" -Value "Pink";
$personalInformationObject | Add-Member -MemberType NoteProperty -Name "Favorite Foods" -Value $foodsObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "Pamela" -Value $personalInformationObject;
#EndRegion /Pamela
$anniversaryObject | Add-Member -MemberType NoteProperty -Name "Location" -Value "Hawaii";
$anniversaryObject | Add-Member -MemberType NoteProperty -Name "Years Together" -Value "62";
if ($parentObject.Children -eq $null)
{
$parentObject | Add-Member -MemberType NoteProperty -Name "Father" -Value "Jason";
$parentObject | Add-Member -MemberType NoteProperty -Name "Mother" -Value "Pamela";
$parentObject | Add-Member -MemberType NoteProperty -Name "Children" -Value $childObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "01/01/1960" -Value $anniversaryObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "anniversary - 01/01/1960" -Value $anniversaryObject;
}
else
{
$parentObject | Add-Member -MemberType NoteProperty -Name "Father" -Value "Jason";
$parentObject | Add-Member -MemberType NoteProperty -Name "Mother" -Value "Pamela";
$parentObject.Children = $childObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "01/01/1950" -Value $anniversaryObject;
$parentObject | Add-Member -MemberType NoteProperty -Name "anniversary - 01/01/1950" -Value $anniversaryObject;
}
#EndRegion Jason and Pamela
I think your elemental object should be a single person with the desired properties, including refences to child objects. Then define a marriage which references the individual people and stores the date & location.
Best to just avoid spaces in property names
Use tab completion to explore what's available through dot notation
FavFoods is created as an array by splitting a string that uses an arbitrary separator (+)
ScriptProperties are used to keep time-dependent values current
Play with the objects generated by this code:
#'
Name,Birthday,FavColor,FavFoods
Jason,01/01/1942,Brown,Grits+Burgers+Malt Drink
Pamela,01/01/1944,Pink,Rice+Cheese+Popsicle
Robert,01/01/1975,Maroon,Burger King+Cheese Pizza+Beer
Thomas,01/01/1978,Yellow,Chicken+Pit Beef+Coke float
Peter,1/1/2000,Red,Spaghetti+Pizza+Ice cream
Andrew,1/1/2002,Green,Big Mac+Soup+Cheesecake
'# | convertFrom-Csv | ForEach {[PSCustomObject]#{
'Name' = $_.Name
'Birthday' = $_.Birthday
'FavColor' = $_.FavColor
'FavFoods' = $_.FavFoods.Split('+')
'Children' = #{}
} | Add-Member -MemberType ScriptProperty -Name Age -Value { ([DateTime]((Get-Date) - [DateTime]($This.Birthday)).Ticks).Year - 1 } -PassTHru
} | FOrEach { $hash = #{} } {
$hash.Add($_.Name,$_)
} { $hash } | sv People
'Jason' , 'Pamela' | ForEach {
$Parent = $_
'Robert' , 'THomas' | ForEach {
$People[$Parent].Children.Add( $_ , $People[$_] )
}
}
'Peter' , 'Andrew' | ForEach {
$People.Robert.Children.Add( $_ , $People[$_] )
}
$Marriage = [PSCustomObject]#{
Spouses = #( $People['Jason'], $People['Pamela'] )
Date = '1/1/1960'
Location = 'Hawaii'
Children = $People['Jason'].Children.Keys + $People['Pamela'].Children.Keys | select -Unique | ForEach {$hash = #{} } { $hash.Add($_ , $People[$_] ) } { $hash }
}
$Marriage | Add-Member -MemberType ScriptProperty -Name 'YearsTogether' -Value { ([DateTime]((Get-Date) - [DateTime]($This.Date)).Ticks).Year - 1 }
Samples:
PS C:\> $People.GetEnumerator() | ForEach { $_.value }
Name : Jason
Birthday : 01/01/1942
FavColor : Brown
FavFoods : {Grits, Burgers, Malt Drink}
Children : {THomas, Robert}
Age : 80
Name : Robert
Birthday : 01/01/1975
FavColor : Maroon
FavFoods : {Burger King, Cheese Pizza, Beer}
Children : {Peter, Andrew}
Age : 47
Name : Pamela
Birthday : 01/01/1944
FavColor : Pink
FavFoods : {Rice, Cheese, Popsicle}
Children : {THomas, Robert}
Age : 78
Name : Thomas
Birthday : 01/01/1978
FavColor : Yellow
FavFoods : {Chicken, Pit Beef, Coke float}
Children : {}
Age : 44
Name : Peter
Birthday : 1/1/2000
FavColor : Red
FavFoods : {Spaghetti, Pizza, Ice cream}
Children : {}
Age : 22
Name : Andrew
Birthday : 1/1/2002
FavColor : Green
FavFoods : {Big Mac, Soup, Cheesecake}
Children : {}
Age : 20
PS C:\>>$Marriage.Children
Name Value
---- -----
THomas #{Name=Thomas; Birthday=01/01/1978; FavColor=Yellow; F...
Robert #{Name=Robert; Birthday=01/01/1975; FavColor=Maroon; F...
PS C:\>>$Marriage.Children.Robert.Children
Name Value
---- -----
Peter #{Name=Peter; Birthday=1/1/2000; FavColor=Red; FavFood...
Andrew #{Name=Andrew; Birthday=1/1/2002; FavColor=Green; FavF...
PS C:\>>$Marriage.Children.Robert.Children.Values | select Name, FavFoods
Name FavFoods
---- --------
Peter {Spaghetti, Pizza, Ice cream}
Andrew {Big Mac, Soup, Cheesecake}

Powershell object doesn't add member

For some reason when I wrote this Powershell object, the last member does not get displayed in my result:
$resultObject = New-Object -TypeName psobject
$resultObject | Add-Member -MemberType NoteProperty -Name Date -Value $date
$resultObject | Add-Member -MemberType NoteProperty -Name TotalPCs -Value $ad
$resultObject | Add-Member -MemberType NoteProperty -Name UnmanagedTotal -Value $total
$resultObject | Add-Member -MemberType NoteProperty -Name TotalEMEA -Value $adEMEA
$resultObject | Add-Member -MemberType NoteProperty -Name UnmanagedEMEA -Value $totalEMEA
$resultObject | Add-Member -MemberType NoteProperty -Name TotalAFRICA -Value $adAFRICA
$resultObject | Add-Member -MemberType NoteProperty -Name UnmanagedAFRICA -Value $totalAFRICA
$resultObject | Add-Member -MemberType NoteProperty -Name TotalAMERICAS -Value $adAMERICAS
$resultObject | Add-Member -MemberType NoteProperty -Name UnmanagedAMERICAS -Value $totalAMERICAS
$resultObject | Add-Member -MemberType NoteProperty -Name TotalAPAC -Value $adAPAC
$resultObject | Add-Member -MemberType NoteProperty -Name UnmanagedAPAC -Value $totalAPAC
$resultObject | ft -AutoSize | out-file -FilePath "C:\BAC\WSUSScripts\KPI\ManagedComputers.txt" -Append
I have no clue why since every info is retrieved the same way and for the other member it all works. The last member just falls off.

InputObject is null - Powershell DataTable

I'm attempting to output an object array (of event logs) to a DataTable with the expectation to pipe into SQL.
The basics are:
Get some forwarded events
Process them to pull some required info out
Output to a data table
function Get-Type
{
param($type)
$types = #(
'System.Boolean',
'System.Byte[]',
'System.Byte',
'System.Char',
'System.Datetime',
'System.Decimal',
'System.Double',
'System.Guid',
'System.Int16',
'System.Int32',
'System.Int64',
'System.Single',
'System.UInt16',
'System.UInt32',
'System.UInt64')
if ( $types -contains $type ) {
Write-Output "$type"
}
else {
Write-Output 'System.String'
}
} #Get-Type
function Out-DataTable
{
[CmdletBinding()]
param([Parameter(Position=0, Mandatory=$true, ValueFromPipeline = $true)] [PSObject[]]$InputObject)
Begin
{
$dt = new-object Data.datatable
$First = $true
}
Process
{
Write-Output "test"
foreach ($object in $InputObject)
{
$DR = $DT.NewRow()
foreach($property in $object.PsObject.get_properties())
{
if ($first)
{
$Col = new-object Data.DataColumn
$Col.ColumnName = $property.Name.ToString()
if ($property.value)
{
if ($property.value -isnot [System.DBNull]) {
$Col.DataType = [System.Type]::GetType("$(Get-Type $property.TypeNameOfValue)")
}
}
$DT.Columns.Add($Col)
}
if ($property.Gettype().IsArray) {
$DR.Item($property.Name) =$property.value | ConvertTo-XML -AS String -NoTypeInformation -Depth 1
}
else {
$DR.Item($property.Name) = $property.value
}
}
$DT.Rows.Add($DR)
$First = $false
}
}
End
{
Write-Output #(,($dt))
}
} #Out-DataTable
$allEvents = Get-WinEvent -LogName ForwardedEvents | Where-Object{$_.Id -ne 111}
$outEvents = #()
$dt = $null
foreach ($curEvent in $allEvents){
$curObj = $null
switch ($curEvent.ID) {
4624 {
$curObj = New-Object -TypeName PSObject
Add-Member -InputObject $curObj -MemberType NoteProperty -Name TimeCreated -Value ([datetime]$curEvent.TimeCreated)
Add-Member -InputObject $curObj -MemberType NoteProperty -Name Action -Value $curEvent.TaskDisplayName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name MachineName -Value $curEvent.MachineName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name UserName -Value ((($curEvent.Message).Split([Environment]::NewLine)[36]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name LoginID -Value ((($curEvent.Message).Split([Environment]::NewLine)[40]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name SourceIP -Value ((($curEvent.Message).Split([Environment]::NewLine)[64]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name ID -Value $curEvent.Id
Add-Member -InputObject $curObj -MemberType NoteProperty -Name RecordID -Value $curEvent.RecordID
}
4647 {
$curObj = New-Object -TypeName PSObject
Add-Member -InputObject $curObj -MemberType NoteProperty -Name TimeCreated -Value ([datetime]$curEvent.TimeCreated)
Add-Member -InputObject $curObj -MemberType NoteProperty -Name Action -Value $curEvent.TaskDisplayName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name MachineName -Value $curEvent.MachineName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name UserName -Value ((($curEvent.Message).Split([Environment]::NewLine)[8]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name LoginID -Value ((($curEvent.Message).Split([Environment]::NewLine)[12]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name SourceIP -Value "Not Available"
Add-Member -InputObject $curObj -MemberType NoteProperty -Name ID -Value $curEvent.Id
Add-Member -InputObject $curObj -MemberType NoteProperty -Name RecordID -Value $curEvent.RecordID
}
4778 {
$curObj = New-Object -TypeName PSObject
Add-Member -InputObject $curObj -MemberType NoteProperty -Name TimeCreated -Value ([datetime]$curEvent.TimeCreated)
Add-Member -InputObject $curObj -MemberType NoteProperty -Name Action -Value "Reconnect"
Add-Member -InputObject $curObj -MemberType NoteProperty -Name MachineName -Value $curEvent.MachineName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name UserName -Value ((($curEvent.Message).Split([Environment]::NewLine)[6]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name LoginID -Value ((($curEvent.Message).Split([Environment]::NewLine)[10]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name SourceIP -Value ((($curEvent.Message).Split([Environment]::NewLine)[24]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name ID -Value $curEvent.Id
Add-Member -InputObject $curObj -MemberType NoteProperty -Name RecordID -Value $curEvent.RecordID
}
4800 {
$curObj = New-Object -TypeName PSObject
Add-Member -InputObject $curObj -MemberType NoteProperty -Name TimeCreated -Value ([datetime]$curEvent.TimeCreated)
Add-Member -InputObject $curObj -MemberType NoteProperty -Name Action -Value "Locked"
Add-Member -InputObject $curObj -MemberType NoteProperty -Name MachineName -Value $curEvent.MachineName
Add-Member -InputObject $curObj -MemberType NoteProperty -Name UserName -Value ((($curEvent.Message).Split([Environment]::NewLine)[8]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name LoginID -Value ((($curEvent.Message).Split([Environment]::NewLine)[12]).split(":")[1]).Trim()
Add-Member -InputObject $curObj -MemberType NoteProperty -Name SourceIP -Value "Not Available"
Add-Member -InputObject $curObj -MemberType NoteProperty -Name ID -Value $curEvent.Id
Add-Member -InputObject $curObj -MemberType NoteProperty -Name RecordID -Value $curEvent.RecordID
}
Default { }
}
$outEvents += $curObj
}
$outEvents
$dt = Out-DataTable -InputObject $outEvents
When I run this, the last output of $outEvents lists all of the event objects with the correct details however trying to pipt it into Out-DataTable returns:
Out-DataTable : Cannot bind argument to parameter 'InputObject' because it is null.
At \\server\scripts\Repository\Write-UserLoginEvent\Write-UserLoginEvent.ps1:140 char:38
+ $dt = Out-DataTable -InputObject $outEvents
+ ~~~~~~~
+ CategoryInfo : InvalidData: (:) [Out-DataTable], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Out-DataTable
I've tried all different methods of formatting the data etc and I can't seem to get this function to accept my custom object array.
If I use a built in function like 'Get-Process' the function works correctly and returns the DataTable so I'm thinking it is something specific to the object I'm returning.
EDIT: Before I posted this, I also moved the DataTable segment into the loop, to attempt to print each event object as an individual DataTable. Hoping to identify where the issue was. It failed immediately on the first object.
So the issue was that I had an un-captured event type that had slipped through.
Because this event was not being formatted correctly there was a single event in the output that would not fit into the DataTable structure, causing the NULL error.
To identify the issue I put an Out-DataTable step inside the loop to process each object individually and in the output I could see that all objects succeeded except one. Tracking down that one I could see that I hadn't catered for that Event ID (8001).

OpenVAS Scan Data Manipulation

enter image description hereI'm attempting to write a Powershell script that takes an OpenVAS .csv file and outputs it in a format that I can upload into Jira. I've written one working script that takes each scan item and creates it's own entry, which definitely has some room for improvement. I've been attempting to create a script that takes all the hosts that has the vulnerability "TCP Timestamps" (as an example) and create only one csv entry.
Starting Input (heavily sanitized):
enter image description here
First working script (makes an individual ticket for each item):
# Function for file picker
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "CSV (*.csv)| *.csv"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
}
$scanImport = #()
$csvContents = #()
$inputFile = Get-FileName "C:\temp"
$scanImport = Import-CSV $inputFile
# Removes the Information vulnerabilities
$scanImport = #($scanImport | Where-Object {$_."Risk Level" -ne "Info"})
$scanImport | Sort Vulnerability | ForEach {
$row = New-Object System.Object
$row | Add-Member -MemberType NoteProperty -Name "Hostname" -Value $_.Hostname
$row | Add-Member -MemberType NoteProperty -Name "IP Address" -Value $_."Host IP"
$row | Add-Member -MemberType NoteProperty -Name "Vulnerability Base Rating" -Value $_."Risk Level"
$row | Add-Member -MemberType NoteProperty -Name "Detection Method" -Value "OpenVAS"
$row | Add-Member -MemberType NoteProperty -Name "Vulnerability Name" -Value $_.Vulnerability.Split("`n")[0]
$row | Add-Member -MemberType NoteProperty -Name "Summary" -Value ($_.Hostname + " - " + $_.Vulnerability.Split("`n")[0])
$row | Add-Member -MemberType NoteProperty -Name "References" -Value ("Observation:" + " " + $_.Observation + "`n`n" + "Remediation:" + " " + $_.Remedation + "`n`n" + "Consequences:" + " " + $_.Consequences + "`n`n" + "Test Output:" + " " + $_."Test Output")
$row | Add-Member -MemberType NoteProperty -Name "Assigned To" -Value user1
$row | Add-Member -MemberType NoteProperty -Name "System Owner" -Value user2
$row | Add-Member -MemberType NoteProperty -Name "Users Affected" -Value "Needs to be entered"
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals" -Value user3
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals1" -Value user4
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals2" -Value user5
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals3" -Value user6
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals4" -Value user7
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals5" -Value user8
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals6" -Value user9
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals7" -Value user10
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals8" -Value user11
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals9" -Value user12
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals10" -Value user13
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals11" -Value user14
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals12" -Value user15
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals13" -Value user16
$csvContents += $row
}
$csvContents | Export-CSV -Path "\Users\$env:USERNAME\Desktop\OpenVAS_to_Jira.csv" -NoTypeInformation
First Script Output (hostnames and vuln names redacted. I used an old vuln scan but out of precaution):
script output
Second Script Attempt (with the grouping functionality):
# Function for file picker
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "CSV (*.csv)| *.csv"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
}
$scanImport = #()
$csvContents = #()
$hostnames = #()
$hostIPs = #()
$vulnList = #()
$counter = 0
$inputFile = Get-FileName "C:\temp"
$scanImport = Import-CSV $inputFile
# Removes the Information vulnerabilities
$scanImport = #($scanImport | Where-Object {$_."Risk Level" -ne "Info"} | Sort Vulnerability)
$scanImport | Sort Vulnerability |
ForEach {
$vulnName = $_.Vulnerability.Split("`n")[0]
$row = New-Object System.Object
if ($scanImport[$counter].Vulnerability -eq $scanImport[($counter+1)].Vulnerability) {
$hostnames += $_.Hostname
$hostIPs += $_."Host IP"
}
else {
if ($hostnames -eq $null) {
$row | Add-Member -MemberType NoteProperty -Name "Summary" -Value ($_.Hostname + " - " + $_.Vulnerability.Split("`n")[0])
$row | Add-Member -MemberType NoteProperty -Name "Hostname" -Value $_.Hostname
$row | Add-Member -MemberType NoteProperty -Name "IP Address" -Value $_."Host IP"
}
else
{
$row | Add-Member -MemberType NoteProperty -Name "Summary" -Value ("Multiple Systems" + " - " + $_.Vulnerability.Split("`n")[0])
$row | Add-Member -MemberType NoteProperty -Name "Hostname" -Value $hostnames
$row | Add-Member -MemberType NoteProperty -Name "IP Address" -Value $hostIPs
$hostnames = #()
$hostIPs = #()
}
$row | Add-Member -MemberType NoteProperty -Name "Vulnerability Base Rating" -Value $_."Risk Level"
$row | Add-Member -MemberType NoteProperty -Name "Detection Method" -Value "OpenVAS"
$row | Add-Member -MemberType NoteProperty -Name "Vulnerability Name" -Value $_.Vulnerability.Split("`n")[0]
$row | Add-Member -MemberType NoteProperty -Name "References" -Value ("Observation:" + " " + $_.Observation + "`n`n" + "Remediation:" + " " + $_.Remedation + "`n`n" + "Consequences:" + " " + $_.Consequences + "`n`n" + "Test Output:" + " " + $_."Test Output")
$row | Add-Member -MemberType NoteProperty -Name "Assigned To" -Value user1
$row | Add-Member -MemberType NoteProperty -Name "System Owner" -Value user2
$row | Add-Member -MemberType NoteProperty -Name "Users Affected" -Value "Needs to be entered"
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals" -Value user3
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals1" -Value user4
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals2" -Value user5
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals3" -Value user6
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals4" -Value user7
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals5" -Value user8
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals6" -Value user9
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals7" -Value user10
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals8" -Value user11
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals9" -Value user12
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals10" -Value user13
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals11" -Value user14
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals12" -Value user15
$row | Add-Member -MemberType NoteProperty -Name "DS: Approvals13" -Value user16
$csvContents += $row
$counter += 1
}
}
$csvContents | Export-CSV -Path "\Users\$env:USERNAME\Desktop\OpenVAS_to_Jira.csv" -NoTypeInformation
Essentially, I want the output to look something like this (excel mock up):
desired output
I know there's a high chance I made quite a bit of errors or didn't code something the right way, but I'd appreciate any feedback and help. Thanks in advance!
$input = Import-Csv "C:\input.csv"
$Vulnerabilities = $input | Group-Object -Property Vulnerability -AsHashTable -AsString
foreach ($Vulnerability in ($Vulnerabilities.Keys | Sort-Object)) {
$row = [PSCustomObject]#{
"Hostname" = (($Vulnerabilities.$Vulnerability.HostName) -join ', ')
"IP Address" = (($Vulnerabilities.$Vulnerability."Host IP") -join ',')
"Vulnerability Base Rating" = ($Vulnerabilities.$Vulnerability)[0]."Risk Level"
"Detection Method" = "OpenVAS"
"Vulnerability Name" = $Vulnerability
}
Export-Csv -InputObject $row -Path "C:\output.csv" -Append -NoTypeInformation
}

Powershell : unable to add the members to collections

I face a problem in following test script.
I expect the following result as the output of it.
VM Name vCPU Memory
------- ---- ------
Server1 1
Server2 8
unfortunately, i am receiving the following output. Can someone help me to understand the mistake in the code?
enter code here
VM Name vCPU
------- ----
Server1 1
Server2
$obj_collection = #()
$report_data = New-Object System.Object
$report_data | Add-Member -MemberType NoteProperty -Name "VM Name" -Value "Server1"
$report_data | Add-Member -MemberType NoteProperty -Name "vCPU" -Value "1"
$obj_collection += $report_data
$report_data = New-Object System.Object
$report_data | Add-Member -MemberType NoteProperty -Name "VM Name" -Value "Server2"
$report_data | Add-Member -MemberType NoteProperty -Name "Memory" -Value "8"
$obj_collection += $report_data
$obj_collection
this? You need to add apple with apple because apple with potatoes can give strange behaviour
$obj_collection = #()
$report_data = New-Object System.Object
$report_data | Add-Member -MemberType NoteProperty -Name "VM Name" -Value "Server1"
$report_data | Add-Member -MemberType NoteProperty -Name "vCPU" -Value "1"
$report_data | Add-Member -MemberType NoteProperty -Name "Memory" -Value $null
$obj_collection += $report_data
$report_data = New-Object System.Object
$report_data | Add-Member -MemberType NoteProperty -Name "VM Name" -Value "Server2"
$report_data | Add-Member -MemberType NoteProperty -Name "vCPU" -Value $null
$report_data | Add-Member -MemberType NoteProperty -Name "Memory" -Value "8"
$obj_collection += $report_data
$obj_collection