I have the following powershell to output a list of IP addresses for failed logon events:
$DT = [DateTime]::Now.AddDays(-1) # check only last 24 hours
$l = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $DT | Select-Object #{n='IpAddress';e={$_.ReplacementStrings[-2]} }
$g = $l | group-object -property IpAddress | where {$_.Count -gt 20} | Select -property Name | export-csv c:\users\export.csv
I'd really like to improve it so it outputs the IP address like it is now, plus the $_.Count. I've tried a few things but I think I'm stuck in SQL world!
I think all you need to do is, in the second pipeline, replace
Select -property Name
with
Select -property Name, Count
(But I would check by looking at the properties on the objects returned from the group-object with get-member first.)
Related
I am querying SCCM database to check the history of users who logged into a computer.
What I have so far works fine however there is a lot of data and I would like to group them all together. For example here is the output for one computer:
These are all logons of the same user (let's say JohnDoe123).
What I want is, instead of having like 30 entries for John, 20 entries for Jane, etc. I want a total of each user. For example:
Computer1 - JohnDoe123 - FullName - Latest time for LastConsoleUse - 500 (total number of console logons) - Latest TimeStamp - 50 000 (total minutes)
You see what I mean?
Obviously I can't sum up the LastConsoleUse and TimeStamp values, so ideally I would like to have just the latest value.
I'm trying ... | Group-Object -property SystemConsoleUser but it's returning an hashtable which isn't the format I'm after:
I'm pretty confused when it comes to manipulating objects within an object like this, so thanks for your help!
#Hist Users SCCM
$ConnexionsUsagers = $null
$poste = "X"
$SiteCode = "X"
$SiteServer = "X"
$ResourceID_Name = (Get-WmiObject -namespace root\sms\site_$SiteCode -computer $SiteServer -query "select ResourceId,Name from SMS_R_SYSTEM where SMS_R_SYSTEM.Name LIKE '%$poste%'")
$ConnexionsUsagers += foreach ($item in $ResourceID_Name) {
$query = #"
SELECT *
FROM SMS_GH_System_SYSTEM_CONSOLE_USER
WHERE SMS_GH_System_SYSTEM_CONSOLE_USER.ResourceID
LIKE '%$($item.ResourceId)%'
"#
Get-WmiObject -Namespace root\sms\site_$SiteCode -Computer $SiteServer -Query $query |
Where-Object {$_.SystemConsoleUser -ne $null} |
Select-Object #{name='Poste';expression={$item.Name}}, SystemConsoleUser,
#{name='Nom complet';expression={Get-ADUser -Properties userprincipalname ($_.SystemConsoleUser -replace "X\\") | Select-Object -ExpandProperty userPrincipalName}},
#{name='LastConsoleUse';expression={[DateTime]::ParseExact(($_.LastConsoleUse).Split('.')[0], "yyyyMMddHHmmss", [System.Globalization.CultureInfo]::InvariantCulture)}},
NumberofConsoleLogons,
#{name='TimeStamp';expression={[DateTime]::ParseExact(($_.TimeStamp).Split('.')[0], "yyyyMMddHHmmss", [System.Globalization.CultureInfo]::InvariantCulture)}},
TotalUserConsoleMinutes
}
$ConnexionsUsagers |
Sort-Object #{expression="Poste"; Ascending=$true}, #{expression="TimeStamp"; Descending=$true} |
Out-GridView
You can achieve the desired result using Group-Object and Measure-Object.
$ConnexionsUsagers | Group-Object -Property SystemConsoleUser |
Select-Object #{n='SystemConsoleUser';e={$_.Name}},
#{n='Poste';e={($_.group | Group-Object -Property Poste -NoElement).Name -join ';'}},
#{n='Nom Complet';e={($_.group | Group-Object -Property "Nom Complet" -NoElement).Name}},
#{n='NumberOfConsoleLogons';e={($_.group.NumberOfConsoleLogons | Measure-Object -Sum).Sum}},
#{n='TotalUserConsoleMinutes';e={($_.group.TotalUserConsoleMinutes | Measure-Object -Sum).Sum}},
#{n='LastConsoleUse';e={$_.group.LastConsoleUse | Sort-Object -Descending | Select-Object -First 1}}
Group-Object -Property PropertyName groups the array of objects by PropertyName. Every unique value of PropertyName will be grouped into a single line or item in the resulting collection. PropertyName values will now be listed under the Name property with all other properties and their values being listed as an array of objects under the Group property. You can then access the Group property to access the remaining ungrouped properties and values. The -NoElement switch leaves off the Group property. It is simply a way to minimize the returned data when it is not needed.
-join operator is used just in case there are multiple computers used by the user. -join ';' joins an array of values into a single string delimited by the semi-colon.
I am trying to get to a point where I have a .csv file including the following information in one line
Date/Time
SourceIP
TargetIP
Low/High/Average latency
Packet Loss
The following command is useful as it returns some detail regarding the low/high and average response times.
Test-Connection $Address -Count 1 |
Measure-Object ResponseTime -Minimum -Average -Maximum |
Export-Csv -Path $FilePath -Append -NoTypeInformation -Force
Returns:
Average Maximum Minimum Property
------- ------- ------- --------
14 14 14 ResponseTime
This command is also useful but doesn't provide the detail on response times
Test-Connection $Address -Count 1 |
Select-Object -Property PSComputerName, IPV4Address, ResponseTime |
Export-Csv -Path $FilePath -Append -NoTypeInformation -Force
Returns:
PSComputerName IPV4Address ResponseTime
-------------- ----------- ------------
XXXXXXXXXXXXXX 8.8.4.4 23
Is there a way of displaying all information in a CSV file on one line, also including the hosts IP address?
The following should do what you want:
$Response = Test-Connection $Address -Count 1
$ResponseTimeMetrics = $Response | Measure-Object ResponseTime -Minimum -Maximum -Average
$ResponseObject = $Response | Select-Object `
PSComputerName,IPv4Address,ResponseTime,
#{name="Minimum";Expression={$ResponseTimeMetrics.Minimum}},
#{name="Maximum";Expression={$ResponseTimeMetrics.Maximum}},
#{name="Average";Expression={$ResponseTimeMetrics.Average}}
$ResponseObject | Export-CSV -Path $FilePath -Append -NoTypeInformation -Force
The $response variable is storing the Test-Connection results. $ResponseTimeMetrics is storing the average, minimum, and maximum values you want from the Measure-Object command. $ResponseObject selects properties already provided by the object stored in $Response and then adding properties from the $ResponseTimeMetrics assigned object. I am using hash tables to add the custom properties to $ResponseObject, so that I can easily name the properties to my liking and provide a value that is not coming from the pipeline.
You can see Select-Object for more information on creating and retrieving object properties with Select-Object.
I need to get VM List which is to be sort by provisionedspace and also those VM should not have RawPhysical. I have tried the below code
Get-Datastore -Name "$DSName" | Get-VMHost | get-vm | Select-Object -Property Name, Provisionedspacegb | sort -Property Provisionedspacegb | select -First 3 | Select Name
The above which is used to get VM list sort by provisionedspacegb
Get-Datastore -Name "$DSName" | Get-VMHost | Get-VM | Get-HardDisk | Where-Object {$_.DiskType -eq "RawPhysical" } | Select Parent
The above which is used to get VM list which does not have Physical Disk
I need those two code in a single line powershell code..
Whenever working with a lot of pipe operators, take a step back and consider divide et impera -approach. That is, break the script in more manageable parts. I don't have VMWare available, but try the following idea:
# Get a list of all the VMs
$allVms= Get-Datastore -Name "$DSName" | Get-VMHost | get-vm
# Array for those we actually want
$rawVms = #()
# Iterate the VM collection. Look for such VMs that have whatever disk config
foreach($vm in $allVms) {
# This filtering statement is likely to be incorrect. Tune accordingly
if($vm | get-harddisk | ? { $_.DiskType -eq "RawPhysical" }).Count -gt 0 {
# If the VM has raw disk, add it into desired VMs list
$rawVms += $vm
}
}
# Do stuff to the filtered collection
$rawVms | Select-Object -Property Name, Provisionedspacegb | ` # ` = line break for readability
sort -Property Provisionedspacegb | select -First 3 | Select Name
The actual syntax is likely to be a bit different.
I Am trying to get a csv of computers that are in a security group "Security Group A" and then filter based on LastlogonTimestamp so that any computers that haven't logged on for 60 days will not be in the result. I have tried a few different ways but i am not having any luck.
I was wondering if anybody can assist.
Currently I have tried
`$lastlogon = (get-date).adddays(-60).ToFileTime()
Get-ADGroupmember "Security Group A" | Select Name
I am not sure how I can pipe this out from here. I have tried using a variable of $comp but i get an error about not being an ad object but rather a system object.
The other option is
$lastlogon = (get-date).adddays(-60).ToFileTime()
Get-ADGroup "Security Group A" -properties members | %{$_.members} | %{get-adcomputer $_ |select name | out-file C:\temp\output.csv
With the last one i have tried to add
-filter {Lastlogontimestamp -gt $lastlogon}
after the $_ and before but that seems to return an empty CSV (i know there are results).
I am doing something wrong...any ideas?
Thanks
Try this
[DateTime]$lastlogon = (get-date).adddays(-60).ToFileTime()
$Computers = Get-ADGroupmember "Security Group A" | Select-Object Name,#{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}}
$Computers | where {$_.lastLogonTimestamp -gt $lastlogon} | select name | out-file C:\temp\output.csv -Force
Tested with a Distribution Group, but should also work in a security group
I was trying to write a simple script to ping a list of computers, and output the result in a table. I ended up doing this, which works fine:
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * | select -expand name | % {
$output = New-Object PSObject
$output | Add-Member NoteProperty "Computer name"($_)
$output | Add-Member NoteProperty "Ping result"("$($(Test-Connection $_ -count 1 -quiet).ToString())")
write $output }
However, I'd like to understand why my first two attempts didn't work, so that I can avoid making the same mistakes later. Here they are:
Script 1: See edit below
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * |
select -expand name | % { $computer = $_; $obj = "" |
select #{Name="Computer";Expression="$computer"},`
#{Name="Pingable";Expression="$($(Test-Connection $computer -count 1 -quiet).ToString())"}
$obj }
Output 1:
Computer Pingable
-----— -----—
Note: Under the table headers, this script actually prints one blank line for each computer I'm pinging.
Script 2:
$table = #{Expression={$_};Label="Computer"},#{Expression={"$($(Test-Connection $_ -count 1 -quiet).ToString())"};Label="Pingable"}
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * | select -expand name | format-table $table
Output 2:
mickeymouse
goofy
minnie
pluto
frank
This one doesn't even output a table...it just prints one computer name per line.
I'd appreciate if someone could explain what's going wrong in these two attempts. Thanks!
Edit: Got Script 1 to work.
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * |
select #{Name="Computer";Expression={$_.Name}},#{Name="Pingable";Expression={"$($(Test-Connection $_.Name -count 1 -quiet).ToString())"}};
Still curious about Script 2
In your second example, you are using the -ExpandProperty of Select-Object which effectively strips the data from the object and outputs an array of strings which format-table then outputs as a list.
See this example:
#First create the array of objects
$rawData = #( #{"Name"="First Obj"; "OtherParam"=1;}, #{"Name"="Second Obj"; "OtherParam"=2;})
$objects = $rawData | %{new-object -type psobject -prop $_}
#Just output the objects
$objects | format-table
Output:
Name OtherParam
---- ----------
First Obj 1
Second Obj 2
Now select the name property, this gives an array of objects with just a single property "name"
$objects | select name | format-table
Output:
Name
----
First Obj
Second Obj
Expand the name property, this gives an array of strings that format table just lists with no heading:
$objects | select -expand name | format-table
Output:
First Obj
Second Obj