Powershell Group Paramter - Count over 100 adds value to variable - powershell

I found the below article to help me group a list of IP addresses.
Using Powershell, how can i count the occurrence of each element in an array?
The command I am currently using is:
get-content c:\temp\temp3.txt | group
This would get the following output:
> Count Name Group
----- ---- -----
3 192.168.1.1 {192.168.1.1, 192.168.1.1, 192.168.1.1}
3 192.168.1.2 {192.168.1.2, 192.168.1.2, 192.168.1.2}
What command can I use to find all IP's with over a count of 5?
I imagine I would need to put my orignal command as a variable like below:
$groupedoutput get-content c:\temp\temp3.txt | group
Unsure where to go from there. Any help would be appreciated.
Thanks,
S

In full:
Get-Content -Path c:\temp\temp3.txt |
Group-Object -NoElement |
Where-Object { $_.Count -gt 5 } |
Select-Object -ExpandProperty Name
In short:
gc c:\temp\temp3.txt | group |? count -gt 5 |% Name
The -NoElement switch means the groups don't gather up all this stuff: {192.168.1.1, 192.168.1.1, 192.168.1.1} , it's not really necessary here but it saves memory if you aren't going to use the grouped items.

Related

How can I use powershell to group process names and show the sum of memory used

I am trying to wrap my head around combining powershell options in order to produce a simple table of the top 10 memory users on my system (server, pc, etc). My PC is Windows 7 with no timeline in site for upgrade to Windows 10 due to Covid 19. I cannot add applications to my work PC that has not gone through a vetting process (read, it takes forever) so most of the time I create my own.
I would like to produce a result that looks something like this:
Count Name Memory Sum in MB
10 Firefox 5000
3 javaw 1000
The order I would like to be able to select by changing a property in the powershell options. So for example, sort by count, name or memory. My sample table is not set in stone.
I have come across the following 2 pieces of powershell and have been trying to adapt them but get errors.
(Get-Process | Measure-Object WorkingSet -sum).sum /1gb
Get-Process | Group-Object -Property Name -NoElement | Where-Object {$_.Count -gt 1}
For sake of learning, I don't mind seeing an "ugly" version and an optimized version.
You can use this:
$proc=ps|select -eXp name;$proc2=#()
$proc|%{
if(!("$($_)" -in $proc2)){$proc2+="$($_)"
$mem=0;ps $_|select -eXp workingSet|%{$mem+=$_/1MB}
[pscustomobject][ordered]#{
'Count'=(ps $_ -ea silentlyContinue).Count
'Name'=$_
'Memory in MB'=$mem
}}}
The PSCustomObject accelerator was introduced in PowerShell v3 so I don't know if the the output looks like a table in Windows 7 however the following pipeline returns desired properties even in PowerShell v2:
Get-Process |
Group-Object -Property Name -NoElement |
Where-Object { $_.Count -gt 1 } |
ForEach-Object {
[PSCustomObject]#{
Count= $_.Count
Name = $_.Name
'Memory Sum in MB' = [math]::Round(( Get-Process -Name $_.Name |
Measure-Object WorkingSet -sum).sum /1Mb, 3)
}
} # | Sort-Object -Property 'Memory Sum in MB'

How to get a numbered count of different items in powershell

Im using the following powershell query to get a list of disks:
Get-NcDisk | Select-Object -Property model | Sort-Object -Property Model -Descending | foreach {$_.model}
It outputs like below:
X316_SMKRE06TA07
X316_HARIH06TA07
X316_HARIH06TA07
X316_HARIH06TA07
How can I get it to output a numbered count of each type of disk like below:
1 X316_SMKRE06TA07
3 X316_HARIH06TA07
Group-Object will do this for you..
I can't use Get-NcDisk but it may just be:
Get-NcDisk | Select-Object -ExpandProperty model | Group-Object
Example output using a string array:
"X316_SMKRE06TA07","X316_HARIH06TA07","X316_HARIH06TA07","X316_HARIH06TA07" | Group-Object
Count Name Group
----- ---- -----
1 X316_SMKRE06TA07 {X316_SMKRE06TA07}
3 X316_HARIH06TA07 {X316_HARIH06TA07, X316_HARIH06TA07, X316_HARIH06TA07}

Using Group-Object : How to Keep x number of each directory and delete all others [duplicate]

I have a network share with 20.000 XML files in the format
username-computername.xml
There are duplicate entries in the form of (when a user received a new comptuer)
user1-computer1.xml
user1-computer2.xml
or
BLRPPR-SKB52084.xml
BLRSIA-SKB50871.xml
S028DS-SKB51334.xml
s028ds-SKB52424.xml
S02FL6-SKB51644.xml
S02FL6-SKB52197.xml
S02VUD-SKB52083.xml
Since im going to manipulate the XMLs later I can't just dismiss properties of the array as at the very least I need the full path. The aim is, if a duplicate is found, the one with the newer timestamp is being used.
Here is a snipet of the code where I need that logic
$xmlfiles = Get-ChildItem "network share"
Here I'm just doing a foreach loop:
foreach ($xmlfile in $xmlfiles) {
[xml]$xmlcontent = Get-Content -Path $xmlfile.FullName -Encoding UTF8
Select-Xml -Xml $xmlcontent -Xpath " "
# create [pscustomobject] etc...
}
Essentially what I need is
if ($xmlfiles.Name.Split("-")[0]) - duplicate) {
# select the one with higher $xmlfiles.LastWriteTime and store either
# the full object or the $xmlfiles.FullName
}
Ideally that should be part of the foreach loop to not to have to loop through twice.
You can use Group-Object to group files by a custom attribute:
$xmlfiles | Group-Object { $_.Name.Split('-')[0] }
The above statement will produce a result like this:
Count Name Group
----- ---- -----
1 BLRPPR {BLRPPR-SKB52084.xml}
1 BLRSIA {BLRSIA-SKB50871.xml}
2 S028DS {S028DS-SKB51334.xml, s028ds-SKB52424.xml}
2 S02FL6 {S02FL6-SKB51644.xml, S02FL6-SKB52197.xml}
1 S02VUD {S02VUD-SKB52083.xml}
where the Group property contains the original FileInfo objects.
Expand the groups in a ForEach-Object loop, sort each group by LastWriteTime, and select the most recent file from it:
... | ForEach-Object {
$_.Group | Sort-Object LastWriteTime -Desc | Select-Object -First 1
}

Powershell counting same values from csv

Using PowerShell, I can import the CSV file and count how many objects are equal to "a". For example,
#(Import-csv location | where-Object{$_.id -eq "a"}).Count
Is there a way to go through every column and row looking for the same String "a" and adding onto count? Or do I have to do the same command over and over for every column, just with a different keyword?
So I made a dummy file that contains 5 columns of people names. Now to show you how the process will work I will show you how often the text "Ann" appears in any field.
$file = "C:\temp\MOCK_DATA (3).csv"
gc $file | %{$_ -split ","} | Group-Object | Where-Object{$_.Name -like "Ann*"}
Don't focus on the code but the output below.
Count Name Group
----- ---- -----
5 Ann {Ann, Ann, Ann, Ann...}
9 Anne {Anne, Anne, Anne, Anne...}
12 Annie {Annie, Annie, Annie, Annie...}
19 Anna {Anna, Anna, Anna, Anna...}
"Ann" appears 5 times on it's own. However it is a part of other names as well. Lets use a simple regex to find all the values that are only "Ann".
(select-string -Path 'C:\temp\MOCK_DATA (3).csv' -Pattern "\bAnn\b" -AllMatches | Select-Object -ExpandProperty Matches).Count
That will return 5 since \b is for a word boundary. In essence it is only looking at what is between commas or beginning or end of each line. This omits results like "Anna" and "Annie" that you might have. Select-Object -ExpandProperty Matches is important to have if you have more than one match on a single line.
Small Caveat
It should not matter but in trying to keep the code simple it is possible that your header could match with the value you are looking for. Not likely which is why I don't account for it. If that is a possibility then we could use Get-Content instead with a Select -Skip 1.
Try cycling through properties like this:
(Import-Csv location | %{$record = $_; $record | Get-Member -MemberType Properties |
?{$record.$($_.Name) -eq 'a';}}).Count

PS: Filter selected rows with only max values as output?

I have a variable results ($result) of several rows of data or object like this:
PS> $result | ft -auto;
name value
---- -----
a 1
a 2
b 30
b 20
....
what I need to get all the rows of name and max(value) like this filtered output:
PS> $result | ? |ft -auto
name value
---- -----
a 2
b 30
....
Not sure what command or filters available (as ? in above) so that I can get each name and only the max value for the name out?
$result | group name | select name,#{n='value';e={ ($_.group | measure value -max).maximum}}
This should do the trick:
PS> $result | Foreach {$ht=#{}} `
{if ($_.Value -gt $ht[$_.name].Value) {$ht[$_.Name]=$_}} `
{$ht.Values}
This is essentially using the Begin/Process/End scriptblock parameters of the Foreach-Object cmdlet to stash input objects with a max value based on a key into a hashtable.
Note: watch out for extra spaces after the line continuation character (`) - there shouldn't be any.