New
#11
Sorry, I wrote ToString() as a description -- not as literal script text. It would be ToString('#,##0')
Sorry, I wrote ToString() as a description -- not as literal script text. It would be ToString('#,##0')
That is exactly what I used yesterday as per the output. The code I posted was the basic code excluding the.ToString('#,##0')
and any other different things that I tried.
Code:--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [245,896] - Sorted by [SeverityID] --- Severity ID Count ----------- ----- 0 1 1 49 2 390 4 6055 5 239401 Total 245,896
Thanks.
Code:@echo off echo. PowerShell ^ $Tot=((Get-MpThreatCatalog) ^| Measure-Object).Count.ToString('#,##0'); ^ $List=(Get-MpThreatCatalog ^| Select SeverityID ^| Group-Object SeverityID, CategoryID ^| Select-Object @{l='SeverityID';e={$_.Group[0].SeverityID}},Count ^| Sort-Object SeverityID ^| Format-Table -AutoSize ^ @{L='Severity ID';E={;if([string]::IsNullOrWhiteSpace($_.SeverityID)) {'-'} else {$_.SeverityID}};A='Left'}, @{L='Count';E={$_.Count.ToString('#,##0')};A='Right'} ^| ^ Out-String -Width 1000).Trim("""`r`n"""); ^ if ($List.Length) {Write-Host """`n`n--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [$Tot] - Sorted by [SeverityID] ---`n`n `n`n$List"""} else ^ {Write-Host """`n`n--- NO Antivirus - Microsoft Defender - Threat(s) Catalogue Entries Available ---"""; exit 1} >> %Temp%\A.txt for /f "delims=" %%i in (%Temp%\A.txt) do echo. %%i PowerShell ^ $Total=((Get-MpThreatCatalog) ^| Measure-Object).Count.ToString('#,##0'); ^ Write-Host """ Total """ -NoNewline; Write-Host """" "$Total""" del %Temp%\A.txtThe second total count is redundant since you already determined $Tot on the first line. It's making it run slower.Code:--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [245.917] - Sorted by [SeverityID] --- Severity ID Count ----------- ----- 0 1 1 2.025 2 385 4 6.055 5 237.451 Total 245.917
Excellent work, Garlin !
Code:@echo off PowerShell ^ $Tot=((Get-MpThreatCatalog) ^| Measure-Object).Count.ToString('#,##0'); ^ $List=(Get-MpThreatCatalog ^| Select SeverityID ^| Group-Object SeverityID, CategoryID ^| Select-Object @{l='SeverityID';e={$_.Group[0].SeverityID}},Count ^| Sort-Object SeverityID ^| Format-Table -AutoSize ^ @{L='Severity ID';E={;if([string]::IsNullOrWhiteSpace($_.SeverityID)) {'-'} else {$_.SeverityID}};A='Left'}, @{L='Count';E={$_.Count.ToString('#,##0')};A='Right'} ^| ^ Out-String -Width 1000).Trim("""`r`n"""); ^ if ($List.Length) {Write-Host """`n`n--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [$Tot] - Sorted by [SeverityID] ---`n`n `n`n$List"""} else ^ {Write-Host """`n`n--- NO Antivirus - Microsoft Defender - Threat(s) Catalogue Entries Available ---"""; exit 1} >> %Temp%\A.txt for /f "delims=" %%i in (%Temp%\A.txt) do echo. %%i PowerShell ^ $Total=((Get-MpThreatCatalog) ^| Measure-Object).Count.ToString('#,##0'); ^ Write-Host """ Total """ -NoNewline; Write-Host """" " $Total""" del %Temp%\A.txtCode:--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [245,919] - Sorted by [SeverityID] --- Severity ID Count ----------- ----- 0 1 1 2,025 2 385 4 6,056 5 237,452 Total 245,919
Yes, that is TRUE.
Great work as usual @garlin. Here is mine amended to accommodate the above:
Code:@echo off PowerShell ^ $Tot=((Get-MpThreatCatalog) ^| Measure-Object).Count.ToString('#,##0'); ^ $List=(Get-MpThreatCatalog ^| Select SeverityID ^| Group-Object SeverityID, CategoryID ^| Select-Object @{L='SeverityID';E={$_.Group[0].SeverityID}}, Count ^| Sort-Object SeverityID ^| Format-Table -AutoSize ^ @{L='Severity ID';E={;if([string]::IsNullOrWhiteSpace($_.SeverityID)) {'-'} else {$_.SeverityID}};A='Left'}, ^ @{L='Count' ;E={;if([string]::IsNullOrWhiteSpace($_.Count)) {'-'} else {$_.Count.ToString('#,##0')}};A='Right'} ^| ^ Out-String -Width 1000).Trim("""`r`n"""); ^ if ($List.Length) {Write-Host """`n`n--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [$Tot] - Sorted by [SeverityID] ---`n`n `n`n$List"""} else ^ {Write-Host """`n`n--- NO Antivirus - Microsoft Defender - Threat(s) Catalogue Entries Available ---"""; exit 1}; ^ Write-Host """"Total """" -NoNewline; Write-Host $Tot >> %Temp%\A.txt for /f "delims=" %%i in (%Temp%\A.txt) do echo. %%i del %Temp%\A.txt echo. & echo ^>Press ANY key to EXIT . . . & pause >nul & Exit
Code:--- Antivirus - Microsoft Defender - Threat(s) Catalogue Entries [245,906] - Sorted by [SeverityID] --- Severity ID Count ----------- ----- 0 1 1 49 2 390 4 6,055 5 239,411 Total 245,906
Of course, the total line could also be written as:
Code:Write-Host """"Total"""" -NoNewline; Write-Host $Tot.PadLeft(14)
Last edited by Paul Black; 28 Apr 2023 at 10:27.
@garlin, the above works excellent.
However, I have tried to insert a blank space before each line of output. So the output starts in column 2 instead of colums 1 if that makes sense. I tried using a$Padding
variable without success. So to show better on a small snippet output for example:
BEFORE:
Code:Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 3 Sub Total: 48
AFTER:
Code:Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 3 Sub Total: 48
Format-Table is column-based, unlike my Get-Modules example which is row-based. FT will auto-size, so if you want to play games then insert padded spaces to the passed data to force placement inside a column. Your data will be treated as a string, instead of a number.
If you just want right-adjusted text, just change FT's column alignment...
Code:@( [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'FriendlyFiles'; Count = 2 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'RemoteAccess'; Count = 43 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'Spyware'; Count = 2 } ) | Format-Table $Padding = ' ' @( [PSCustomObject]@{ 'Severity ID' = $Padding + 1; 'Threat Name' = 'FriendlyFiles'; Count = 2 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'RemoteAccess'; Count = 43 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'Spyware'; Count = 2 } ) | Format-Table @( [PSCustomObject]@{ 'Severity ID' = $Padding + $Padding + 1; 'Threat Name' = 'FriendlyFiles'; Count = 2 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'RemoteAccess'; Count = 43 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'Spyware'; Count = 2 } ) | Format-TableCode:Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 2 Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 2 Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 2
A BIG thank you as always @garlin,
As it seemed like a LOT of work to incorporate the changes I wanted into the whole code [ and I didn't really understand it to be honest ], I converted the PS code toBatch
[ as part of my 'Comprehensive' Script ] and then output the data to a%Temp%
file and called it back putting a blank space at the front of each row and keeping the existing blank rows [ it took a while for me to figure it out ! ]:
Code:@echo off setlocal EnableDelayedExpansion PowerShell ^ $Catalog = @{}; ^ Get-MpThreatCatalog -ErrorAction Ignore ^| ^ ForEach-Object {^ $Severity = $_.SeverityID; ^ $ThreatName = ($_.ThreatName -Split ':')[0]; ^ if (-NOT $Catalog.ContainsKey($Severity)) { ^ $Catalog[$Severity] += @{ $ThreatName = 1 } ^ } else { ^ $Catalog[$Severity][$ThreatName] = $Catalog[$Severity][$ThreatName] + 1 ^ } ^ }; ^ $Total = 0; ^ ForEach ($Severity in ($Catalog.GetEnumerator() ^| Select Name ^| Sort-Object -Property Name)) { ^ $Summary = @(); ^ $Subtotal = 0; ^ $Severity = $Severity.Name; ^ ForEach ($ThreatName in ($Catalog[$Severity].GetEnumerator() ^| Select Name ^| Sort-Object -Property Name)) { ^ $Count = $Catalog[$Severity][$ThreatName.Name]; ^ $Summary += [PSCustomObject]@{ ^ SeverityID = $Severity; ^ ThreatName = '{0,-22}' -f $ThreatName.Name; ^ Count = '{0,6:N0}' -f $Count}; ^ $Subtotal += $Count; ^ $Total += $Count ^ }; ^ ($Summary ^| Format-Table ^ @{L='Severity ID';E={;if([string]::IsNullOrWhiteSpace($_.SeverityID)) {'-'} else {$_.SeverityID}};Align='Center'}, ^ @{L='Threat Name';E={;if([string]::IsNullOrWhiteSpace($_.ThreatName)) {'-'} else {$_.ThreatName}}}, ^ @{L='Count' ;E={;if([string]::IsNullOrWhiteSpace($_.Count)) {'-'} else {$_.Count}};Align='Right'} ^| ^ Out-String) -Replace('`n`r',''); '{0,41}' -f ('Sub Total: {0:N0}' -f $Subtotal) ^ }; ^ """`n{0,41}""" -f ('Total: {0:N0}' -f $Total) >> %Temp%\A.txt PowerShell ^ (Get-Content -Raw %Temp%\A.txt).Replace("""`r`n`r`n`r`n""", """`r`n""") ^| Out-File %Temp%\A.txt -Encoding ASCII for /f "delims=" %%L in ('findstr /N "^" "%Temp%\A.txt"') do ( set "line=%%L" set "line=!line:*:=!" echo( !line!) del %Temp%\A.txt echo ^>Press ANY key to EXIT . . . & pause >nul & Exit
MY OUTPUT:
Code:Severity ID Threat Name Count ----------- ----------- ----- 0 Unknown 1 Sub Total: 1 Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 3 Sub Total: 48 Severity ID Threat Name Count ----------- ----------- ----- 2 EUS 2 2 Joke 277 2 Program 5 2 SettingsModifier 49 2 Spyware 7 2 Tool 49 2 TrojanClicker 1 Sub Total: 390 Severity ID Threat Name Count ----------- ----------- ----- 4 Adware 782 4 BrowserModifier 566 4 HackTool 2,998 4 Misleading 385 4 MisleadingAd 37 4 Program 564 4 SoftwareBundler 270 4 Spyware 171 4 Trojan 308 4 TrojanClicker 5 4 Worm 1 Sub Total: 6,087 Severity ID Threat Name Count ----------- ----------- ----- 5 App 3 5 Backdoor 20,418 5 Behavior 13,056 5 Constructor 539 5 DDoS 354 5 Dialer 141 5 DoS 386 5 EUS 19 5 Exploit 10,066 5 Flooder 45 5 MagicThreat_7ffe3a4b 1 5 MonitoringTool 717 5 Nuker 45 5 Phish 2 5 Program 5 5 PUA 1,723 5 PUAAdvertising 52 5 PUABundler 45 5 PUADlManager 75 5 PUAMarketing 2 5 PUAMiner 48 5 PUATorrent 27 5 PWS 9,410 5 Ransom 4,987 5 Rogue 131 5 SettingsModifier 1 5 Spammer 516 5 Spoofer 45 5 Spyware 28 5 SupportScam 160 5 Tool 2 5 Trojan 73,220 5 TrojanClicker 1,172 5 TrojanDownloader 30,499 5 TrojanDropper 7,515 5 TrojanNotifier 53 5 TrojanProxy 1,570 5 TrojanSpy 8,615 5 VirTool 10,204 5 Virus 27,541 5 Worm 17,209 Sub Total: 240,647 Total: 247,173 >Press ANY key to EXIT . . .
Last edited by Paul Black; 07 Jul 2023 at 12:40.
Your 2nd example was easier to understand on your intentions. Convert Format-Table from an object to Out-String, then split into separate lines before padding.
Code:$Output = @( [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'FriendlyFiles'; Count = 2 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'RemoteAccess'; Count = 43 } [PSCustomObject]@{ 'Severity ID' = 1; 'Threat Name' = 'Spyware'; Count = 2 } ) | Format-Table | Out-String $Output -split "`n" | foreach { ' ' + $_ }Code:PS C:\Users\GARLIN\Downloads> .\PB.ps1 Severity ID Threat Name Count ----------- ----------- ----- 1 FriendlyFiles 2 1 RemoteAccess 43 1 Spyware 2
Ideally your goal is to do all output processing in PS, and not have to resort to external temp files or calling CMD commands for that work.