Get the latest date - arrays

I have an array that I call $data.
I want to get the earliest dates from the $data array for each host in my csv file. The user will input a host and it will find the earliest date it was modified.
Hostname LastModified
HD 9/8/2012
LOG 9/15/2004
NETMAN 12/25/2004
NETMAN 5/5/2015
LOG 1/4/2013
LOG 6/6/2011
So if they input LOG, I want it to give me the earliest date.
Created on 9/15/2004
Code:
$data= import-csv ".\Earliest Date Template.csv"
$Hostname=Read-Host "Please enter Host Name"
$data | Foreach-Object {$_."Last Modified" = [DateTime]$_."Last Modified"; $_} | Group-Object Hostname| Foreach-Object {$_.Group | Sort-Object LastModified | Select-Object -First 1}

Grouping them does seem like the way to go but you don't need to do that. Just sort the entire list by date then select the last option from the list (that matches the host name you are looking for).
$hostname = Read-Host "Please enter Hostname"
$data | Sort-Object {[DateTime]$_."LastModified"} | Where-Object{$_.Hostname -eq $hostname} | Select -Last 1
You might need to do some user validation but something like this seems to work with your sample data:
Please enter Hostname: log
Hostname LastModified
-------- ------------
LOG 1/4/2013
If you then only want the date it would just be a matter of expanding the value from the result.
$data |
Sort-Object {[DateTime]$_."LastModified"} |
Where-Object{$_.Hostname -eq $hostname} |
Select -Last 1 -ExpandProperty LastModified

Related

Selecting Distinct Items within Array using PowerShell and Linq

I have been banging my head on this problem for a few hours.
I have a multi-dimensional array and I need to select the unique items based on two "columns".
Is there an efficient .Net or otherwise way to do this and achieve the desired output?
The data looks something like:
ComputerName, IPAddress, MacAddress, FirstObserved
I would like to determine unique values based on MacAddress and ComputerName and keep the unique value based on the oldest FirstObserved date.
I have tried the PowerShell ways of doing this but it's horribly slow to say the least.
$data | Group-Object -Property ComputerName,MacAddress | ForEach-Object{$_.Group | Sort-Object -Property FirstObserved | Select-Object -First 1}
In a perfect world I would have a list of items no duplicates with the oldest entry based on FirstObserved date.
You can implement the grouping manually with a hashtable:
$FirstObserved = #{}
Import-Csv .\data.csv |ForEach-Object {
$key = $_.Computername,$_.MacAddress -join ','
$date = $_.FirstObserved -as [datetime]
# Check if we already have an entry for this Name + MAC combo
if($FirstObserved.Contains($key))
{
# Make sure the current date is older than what we have already
if($FirstObserved[$key] -gt $date)
{
$FirstObserved[$key] = $date
}
}
else
{
# First instance of the Name + MAC combo, save the date
$FirstObserved[$key] = $date
}
}
Now you can eaily look up the first date for a combination with:
$FirstObserved["Computer-01,11:22:33:44:55:66"]
If you want to export the list to another csv, all you need to do is turn the key-value pairs of the hashtable into objects:
$FirstObserved |Select-Object #{Name='Identity';Expression={$_.Key}},#{Name='FirstObserved';Expression={$_.Value}} |Export-Csv -Path output.csv

Export specific output from an array

I have the below code that displays all groups that users which have a SamAccountName starting with 'X' are members of, and that exports the output in a CSV file:
Get-ADUser -Filter {SamAccountName -like "X*"} -Properties memberof |
Select name, #{N="MemberOf";E={$_.memberof -join ";"}} |
Export-Csv "C:\Users\chicken\Desktop\export_powershell\extract_test.csv"
The code works fine, but I have some problems with the output. Indeed it returns all groups that users are members of, but I only need to export one specific group (the group that starts by 'G-ORG') for each user.
How can I filter the output to only have groups that start with 'G-ORG' for each user?
Example output:
User1,"CN=YVD_Access; CN=Proxy_ACCESS_GD; CN=RVH_BIS HSBC; CN=G-ORG-MULTI-CANAL-APPLICATION; CN=......"
USER2,"CN=G-ORG-ARCHI; CN=Proj_X; CN=Proj_X; CN=X_REF; CN=......"
USER3,"CN=HAV_SH; CN=G-ORG-IT; CN=EPH; CN=......"
USER...
Required output:
User1,"CN=G-ORG-MULTI-CANAL-APPLICATION"
USER2,"CN=G-ORG-ARCHI"
USER3,"CN=G-ORG-IT;"
USER...
Simply filter the member list for distinguished names that begin with CN=G-ORG- instead of joining all of them:
$_.memberof | Where-Object { $_.StartsWith('CN=G-ORG-') }
If there could be more than one match you can then either join the results
($_.memberof | Where-Object {...}) -join ';'
or select one of them (e.g. the first)
$_.memberof | Where-Object {...} | Select-Object -First 1
depending on the requirements.

"Normalizing" a CSV file

I have a CSV file for help desk calls. The same ticket might have 1,2, or even 5 records based on the number of updates it has. (One field is different, all other fields are identical).
I want to take the mostly-duplicate records and create one record with the differences concatenated into it. Having programmed in the past, but being a newbie to PowerShell, I could use some help.
So, based on a previous question I asked, here's what I have so far. Assuming data like this:
ID, Date, Comment
345, 1/1/16, Moss has reported a fire in the I/T Room
345, 1/1/16, Never mind, he has sent an e-mail about it.
346, 1/2/16, Someone on the 5th floor is complaining about a man under her desk.
347, 2/1/16, Jen says she has broken the Internet.
347, 2/1/16, Douglas is very angry, we need a fix ASAP!
347, 2/1/16, Roy was playing a joke on her. Closing ticket.
I have the following code:
$FileList = Import-Csv "Call List.csv"
$incidents = $FileList | Group ID
foreach($group in $incidents)
{
# What goes here?
}
How do I take the comments from the 2nd, 3rd, etc. line in the group, concatenate it to the comment in the first, and write the file out?
The Group-Object produces an object with Name and Group, Group containing all the items in that group. You can extract them and create a new object using something like this:
$incidents = $FileList | Group-Object ID | % {
New-Object psobject -property #{
ID = $_.Name
Date = $_.Group[0].Date
Comment = ($_.Group | Select -Expandproperty Comment) -Join "`n"
}
}
(not tested as I am currently on a Mac)
I'd first get a list of the unique IDs, for example:
$Ids = $FileList | Select-Object -ExpandProperty Id -Unique
Then I'd look through the list of tickets and build up a "report" for each ID:
foreach($Id in $Ids){
# Get all incident logs for this Id:
$logs = $FileList | ?{$_.Id -eq $Id}
$report = ""
foreach($log in $logs){
$report += $log.Date + ": " + $log.Comment + "; "
}
# Now you can write the text out
$report | Out-File $Outfile -Append
}
Hope that gives you an idea.

Powershell add like rows together value in column 2

I have been searching for a way to do this in PowerShell, but I have had no luck. I have a file that looks like this.
Column1,column2
A,1
B,2
C,3
D,4
A,2
B,3
D,6
A,3
C,2
I would like to find a way that I could sort through this file and add column2 and end up with a file that would look like this.
column1,column2
A,6
B,5
C,5
D,10
Any help would be greatly appreciated.
Combination of Group-Object and Measure-Object would accomplish this for you. Provided you have PowerShell 3.0 or higher...
Import-Csv c:\temp\test.csv | Group-Object Column1 | ForEach-Object{
[pscustomobject][ordered]#{
Column1 = $_.Name
Column2 = $_.Group.Column2 | Measure-Object -Sum | Select-Object -ExpandProperty Sum
}
} | Export-Csv -NoTypeInformation C:\temp\testOutput.csv
If you have issues with either of these cmdlets please consult the documentation or debug my script to see what it is doing.
Could also use calculated properties with the similar logic and same output. Should work on lower PowerShell versions as well.
Import-Csv c:\temp\test.csv |
Group-Object Column1 |
Select #{Label="Column1";Expression={$_.Name}},#{Label="Column2";Expression={$_.Group.Column2 | Measure-Object -Sum | Select-Object -ExpandProperty Sum}} |
Export-Csv -NoTypeInformation C:\temp\testOutput.csv

Get files (in folder,subfolder from a drive) based on last access parameter in powershell

I want a script to list all files in folder/subfolder with a particular last access date.
I have a script to show a subfolder:
get-childitem -Recurse | Where {$_.psIsContainer -eq $true} | select {$_.Fullname}
Thank you for your help.
Get-ChildItem -Recurse | ? { $_.lastaccesstime -ge [datetime]"12/18/11"} | select fullname
this give you a files's list with lastaccesstime attribute greater or equal 18 december 2011 00.00 am.
Get-ChildItem -Recurse | ? { $_.lastaccesstime -ge [datetime]"12/01/11" -and $_.lastaccesstime -lt [datetime]"12/02/11"} | select fullname
this give all file with lastaccesstime in date december 01 2011 from 00.00am to 11.59pm
lastaccesstime is a complete reference to date and time, that's why you need to specifies a range for a single date match.

Resources