Summing an array of Objects in Powershell - powershell

I have an array of objects that are holding integer values.
$row = new-Object PSObject # create a new object to hold its data
$row | Add-Member -Name "sheet_number" -MemberType NoteProperty -Value 1
$row | Add-Member -Name "frame_number" -MemberType NoteProperty -Value 2
$row | Add-Member -Name "sheet_height" -MemberType NoteProperty -Value 1200
$row | Add-Member -Name "frame_height" -MemberType NoteProperty -Value 1200
$row | Add-Member -Name "frame_width" -MemberType NoteProperty -Value 3300
$row | Add-Member -Name "orientation" -MemberType NoteProperty -Value 0
$frames += $row
this is in a for loop intended to iterate through several times. But the sheet_number property should only have a couple values. what I need is to sum up the values in frame_width where the sheet_number is the same.
Pseudo Code:
sheet_width = sum of frame_width where sheet number = 1

Use a combination of Where-Object, ForEach-Object, and Measure-Object:
$sum = (
$frames |
Where-Object sheet_number -eq 1 |
ForEach-Object frame_width |
Measure-Object -Sum
).Sum
To do it for all sheet numbers, additionally use Group-Object:
$arrayOfSums =
$frames |
Group-Object sheet_number |
ForEach-Object {
($_.Group.frame_width | Measure-Object -Sum).Sum
}

Related

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 list recursively files attributes to csv

I am trying to fill a csv file with all the attributes of the files contained within a folder. I have troubles recovering the fileversion & assembly
$arr = #()
gci C:\Temp -recurse | ? {$_.PSIsContainer -eq $False} | % {
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Directory $_.DirectoryName
$obj | Add-Member NoteProperty Name $_.Name
$obj | Add-Member NoteProperty Size (Get-Item $_.Length/1MB)
$obj | Add-Member NoteProperty Owner ((Get-ACL $_.FullName).Owner)
$obj | Add-Member NoteProperty LastAccess $_.LastAccessTime
$obj | Add-Member NoteProperty Extension $_.Extension
$obj | Add-Member NoteProperty Creation $_.CreationTime
$obj | Add-Member NoteProperty LastWrite $_.LastWriteTime
$obj | Add-Member NoteProperty ReadOnly $_.IsReadOnly
$obj | Add-Member NoteProperty FullName $_.FullName
$obj | Add-Member NoteProperty Date (Get-Date -format "yyyy-MM-d HH:mm")
$obj | Add-Member NoteProperty Version ($_.FileVersion)
$obj | Add-Member NoteProperty Assembly ($_.AssemblyVersion)
$arr += $obj
}
$arr | Export-CSV -notypeinformation "c:\temp\File\report.csv"
try this
$arr = #()
gci C:\Temp -recurse -File -Filter *.dll | % {
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Directory $_.DirectoryName
$obj | Add-Member NoteProperty Name $_.Name
$obj | Add-Member NoteProperty Size (Get-Item $_.Length/1MB)
$obj | Add-Member NoteProperty Owner ((Get-ACL $_.FullName).Owner)
$obj | Add-Member NoteProperty LastAccess $_.LastAccessTime
$obj | Add-Member NoteProperty Extension $_.Extension
$obj | Add-Member NoteProperty Creation $_.CreationTime
$obj | Add-Member NoteProperty LastWrite $_.LastWriteTime
$obj | Add-Member NoteProperty ReadOnly $_.IsReadOnly
$obj | Add-Member NoteProperty FullName $_.FullName
$obj | Add-Member NoteProperty Date (Get-Date -format "yyyy-MM-d HH:mm")
$obj | Add-Member NoteProperty Version ($_.VersionInfo.FileVersion)
$obj | Add-Member NoteProperty Assembly ([Reflection.AssemblyName]::GetAssemblyName($_.FullName).Version)
$arr += $obj
}
$arr | Export-CSV -notypeinformation "c:\temp\File\report.csv"
you can simplify your code like this
gci C:\Temp -recurse -File -Filter *.dll | % {
New-Object PSObject -Property #{
Directory= $_.DirectoryName
Name= $_.Name
Size= $_.Length/1MB
Owner= ((Get-ACL $_.FullName).Owner)
LastAccess= $_.LastAccessTime
Extension= $_.Extension
Creation= $_.CreationTime
LastWrite= $_.LastWriteTime
ReadOnly= $_.IsReadOnly
FullName= $_.FullName
Date= (Get-Date -format "yyyy-MM-d HH:mm")
Version= ($_.VersionInfo.FileVersion)
Assembly= ([Reflection.AssemblyName]::GetAssemblyName($_.FullName).Version)
}
} | Export-CSV -notypeinformation "c:\temp\File\report.csv"
1)The issue what you are facing is because of permission. Try running the script in elevated mode(run as administrator).
2)You should not try to save anything under C:\temp folder. Better to create a folder in D:\ or E:\ and put it over there as D:\temp_dump\report.csv
3)if you are putting get-item on the size, then that is not a valid one since you have to pick whatever inside the folder.
Below Script is working fine.
##########################################################
$arr = #()
$Folder_path="E:\PS"
gci $Folder_path | ? {$_.PSIsContainer -eq $False} | % {
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Directory $_.DirectoryName
$obj | Add-Member NoteProperty Name $_.Name
$obj | Add-Member NoteProperty Size (Get-ChildItem $Folder_path | Measure-Object -property length -sum)
$obj | Add-Member NoteProperty Owner ((Get-ACL $_.FullName).Owner)
$obj | Add-Member NoteProperty LastAccess $_.LastAccessTime
$obj | Add-Member NoteProperty Extension $_.Extension
$obj | Add-Member NoteProperty Creation $_.CreationTime
$obj | Add-Member NoteProperty LastWrite $_.LastWriteTime
$obj | Add-Member NoteProperty ReadOnly $_.IsReadOnly
$obj | Add-Member NoteProperty FullName $_.FullName
$obj | Add-Member NoteProperty Date (Get-Date -format "yyyy-MM-d HH:mm")
$obj | Add-Member NoteProperty Version ($_.FileVersion)
$obj | Add-Member NoteProperty Assembly ($_.AssemblyVersion)
$arr += $obj
}
$arr | Export-CSV -notypeinformation "E:\report.csv"
#
In order to get fileversion you have to use this:
$obj | Add-Member NoteProperty Version ($_.VersionInfo.FileVersion)
You cannot get AssemblyVersion from VersionInfo

Powershell: File properties - Bytes to Mb

Currently have the following script that outputs some file data to a report. The file length is in bytes though and wondering how I can convert that to MB before outputting to the array.
$arr = #()
gci C:\stuff -recurse | ? {$_.PSIsContainer -eq $False} | % {
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Directory $_.DirectoryName
$obj | Add-Member NoteProperty Name $_.Name
$obj | Add-Member NoteProperty Length $_.Length
$obj | Add-Member NoteProperty created $_.creationtime
$obj | Add-Member NoteProperty Access $_.LastAccessTime
$obj | Add-Member NoteProperty LastWritten $_.LastWriteTime
$obj | Add-Member NoteProperty Extension $_.Extension
$obj | Add-Member NoteProperty Owner ((Get-ACL $_.FullName).Owner)
$arr += $obj
}
$arr | Export-CSV -notypeinformation "c:\files.csv"
When converting into MB, just put brackets around it:
$obj | Add-Member NoteProperty Length ($_.Length/1MB)
or maybe more useful:
$obj | Add-Member NoteProperty MB ("{0:N3}" -f ($_.Length/1MB))
to only show the first three digits after the point.

Powershell: Sort percent number

Got a small problem with sorting percent numbers.
I just wrote a simple script to test:
function get-percent{
$obj1 = New-Object PSObject
$percentUsed1="{0:P0}" -f (100/100)
$obj1 | Add-Member -membertype NoteProperty -Name 'Percent' -Value $percentUsed1
$obj2 = New-Object PSObject
$percentUsed2="{0:P0}" -f (99/100)
$obj2 | Add-Member -membertype NoteProperty -Name 'Percent' -Value $percentUsed2
$obj3 = New-Object PSObject
$percentUsed3="{0:P0}" -f (8/100)
$obj3 | Add-Member -membertype NoteProperty -Name 'Percent' -Value $percentUsed3
$obj4 = New-Object PSObject
$percentUsed4="{0:P0}" -f (70/100)
$obj4 | Add-Member -membertype NoteProperty -Name 'Percent' -Value $percentUsed4
write $obj1
write $obj2
write $obj3
write $obj4
}
get-percent | sort-object 'Percent' -descending |ft
Here is what i get:
Percent
99%
8%
70%
100 %
Normally, I should have: 100 % , 99%, 70%...
Any ideas guys ?
Thx.
Try:
get-percent | sort-object { [INT]($_.percent -replace '%') } -descending
In this way sort-object can sort by [INT] and not by [String] as before.

Odd PowerShell behavior and Add-Member

Can someone help me understand why the $_ works differently for the Add-Member function than it seems to for other PowerShell functions? There must be some nuance that I am missing here.
Using the sample CSV file below, the first 3 examples work fine. The fourth, which seems pretty straightforward, does not. The error Powershell returns is:
The variable '$_' cannot be retrieved because it has not been set.
Is this "normal" or have I miscoded something?
Thanks in advance.
Test.csv
Column1,Column2, Column3
Rock,1,abc
Paper,2,efg
Scissors,3,hij
$obj = Import-CSV "C:\test.csv"
(1) $obj | Add-Member -MemberType NoteProperty -Name IdNumber -value "ROCK" -PassThru| Format-Table
(2) $obj | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name IdNumber -value $_.Column1 ; $_} | Format-Table
(3) $obj | ForEach-Object { Add-Member -InputObject $_ -MemberType NoteProperty -Name IdNumber -value $_.Column1 ; $_ } | Format-Table
(4) $obj | Add-Member -MemberType NoteProperty -Name IdNumber -value $_.Column1 -PassThru| Format-Table
When you do this:
$obj | Add-Member -MemberType NoteProperty -Name IdNumber -value $_.Column1 -PassThru
You are accessing $_ outside of a pipeline bound context e.g. inside a foreach-object expression or within a scriptblock value specified for a pipeline bound parameter. The Value parameter is not pipeline bound. If it were you would be able to do this:
$obj | Add-Member -MemberType NoteProperty -Name IdNumber -value {$_.Column1} -PassThru
As it stands, the easiest way to do what you want is:
$obj | ForEach-Object { Add-Member -Inp $_ NoteProperty -Name IdNumber -Value $_.Column1 -PassThru } | Format-Table