check file last modified date - powershell

I have the following line of code:
Get-Item \\MachineNAME\c$\Windows\System32\GroupPolicy\Machine\Registry.pol |
Foreach {$_.LastWriteTime}
This returns the last modified date of a given machine successfully. Using Out-File I can write the single result to a text file.
What I would really like to do it read in a list of machine names I have and output all the results to a text file. This would show a list of machines and the last modified date next to it.

assuming you have one machine per line in c:\temp\computers.txt, something like this could do the trick
get-content c:\temp\computers.txt | %{
$lwt= ls \\$_\c$\Windows\System32\GroupPolicy\Machine\Registry.pol | select -expand lastWriteTime
echo "$_ : $lwt" >> c:\temp\results.txt
}

Related

Save the output from a Powershell command to a variable

im trying to save the output from a command to a variable,
but i just cant get it to work.
It should look something like this :
$test = (Get-SmbShare | Select Name,CurrentUsers,CurrentUserLimit | fl)
Write-Host $test
Output: The Output of Get-SmbShare
I was looking through the comments and I saw you said that you want to store it in a text file.
#Lee_Dailey Thats what i want to do, the output is gonna go into a text file. – Jan
So if you want to skip the variable part and just send it straight to a text file, you could use:
Get-SmbShare | Select Name, CurrentUsers, CurrentUserLimit | fl | Out-File -filepath "C:\Temp\file.txt"

How to extract a value out of a file, and save it in a new file, using Powershell

I recently started using Powershell and I'm trying out some code.
I have a .cfg file with several rules of code. The code is written like this:
ad.name=1
ad.virtual=active
ad.set=none
ad.partition=78
Now I want to export the value of ad.partition, which is 78, to a new file. I don't want to export ad.partition or = but only the number 78.
So far I got this:
Get-Content -Path C:\file.cfg | Where-Object {$_ -like 'ad.partition=78'}
But then I -obviously- just get the variable and the value. Not sure how to continue...
I hope someone has a way of achieving what I want.
After saving the value in a new file, would it be possible to add spaces? For example, the value consists out of 9 digits, e.g. 123456789. The desired output result would be 123 456 789.
Use ConvertFrom-StringData cmdlet to create a hash table from your file, then simply index the key you are after:
$h=(Get-Content -Path C:\file.cfg | ConvertFrom-StringData)
$h.("ad.partition") -replace ('^(\d{1,3})(\d{1,3})?(\d{1,3})?','$1 $2 $3') > C:\out.cfg
You can use the Select-String cmdlet to capture your desired value using a regex. Then just pipe the result to the Out-File cmdlet. To get your desired output with spaces, you can use a simple format string:
"{0:### ### ###}" -f [int](Select-string 'ad\.partition=(.*)' -Path C:\file.cfg).Matches.Groups[1].Value |
Out-File C:\result.cfg

Filtering and sorting log lines in PowerShell according to date string

I have two separate scripts that do this process. First one looks at the large log and filters out specific lines from that long and puts them into a new log file. Then I have a second script that reads first ten characters of each line from that new log file (these actually represent the date of the log entry as yyyy-mm-dd), and based on that date, it puts that whole line of the log file into a new target file, whose name is based on that date (targetfile-yymmdd.log). Since my original logs tend to contain dates that span two or more dates, I need to sort them out so that each final log file only contains entries for one date, and so that the file name reflects that actual date.
I would like to consolidate these two scripts into one: read the line from the log, check if it matches the filter, if it does, check the first ten characters and then dump the line in the appropriate target file. Here are the basics, as I have them now:
Script 1 reads through a large log file (standard Apache htaccess log) and filters out lines based on a specific pattern, putting them in a new file:
$workingdate = [today's date as yymmdd ]
Get-Content "completelog-$workingdate.log" -ReadCount 200000 |
foreach {
$_ -match "(/(jsummit|popin|esa)/)" |
Add-Content "D:\logs\filteredlog-$workingdate.log"
}
Script 2 then goes through the new file and looks at the first ten characters from each line, which contain standard date as yyyy-mm-dd. It copies that line into a new file by the name targetfile-ddmmyy.log, where the date is based on the actual date from the line:
$file = "filtered-$workingdate.log" (where $workingdate is today's date as yymmdd)
$streamReader = New-Object System.IO.StreamReader -Arg "$file"
while($line = $streamReader.ReadLine()){
$targetdate = $([datetime]::ParseExact($line.Substring(0,10), 'yyyy-mm-dd', $null).ToString('yymmdd'))
$targetfile = "targetfile-$targetdate.log"
$line | Add-Content $targetfile
}
Separetely, these two work well, but since my log file is over 20GB, I'd like to cut down on the time it takes to go through these logs (twice).
You could work with each matched line and skip creating the intermediate file.
(Get-Content "completelog-$workingdate.log" -ReadCount 200000) |
%{ $_ } | ?{ $_ -match $REGEX } | %{
$targetdate = '{0:yyMMdd}' -f $(Get-Date $_.Substring(0,10));
$_ | Add-Content "targetfile-$targetdate.log"
}
Although I am not sure this will improve overall performance. Testing this on a 5MB file took about 100 seconds.

PowerShell find most recent file

I'm new to powershell and scripting in general. Doing lots of reading and testing and this is my first post.
Here is what I am trying to do. I have a folder that contains sub-folders for each report that runs daily. A new sub-folder is created each day.
The file names in the sub-folders are the same with only the date changing.
I want to get a specific file from yesterday's folder.
Here is what I have so far:
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | where(get-date).AddDays(-1)
Both parts (before and after pipe) work. But when I combine them it fails.
What am I doing wrong?
What am I doing wrong?
0,1,2,3,4,5 | Where { $_ -gt 3 }
this will compare the incoming number from the pipeline ($_) with 3 and allow things that are greater than 3 to get past it - whenever the $_ -gt 3 test evaluates to $True.
0,1,2,3,4,5 | where { $_ }
this has nothing to compare against - in this case, it casts the value to boolean - 'truthy' or 'falsey' and will allow everything 'truthy' to get through. 0 is dropped, the rest are allowed.
Get-ChildItem | where Name -eq 'test.txt'
without the {} is a syntax where it expects Name is a property of the thing coming through the pipeline (in this case file names) and compares those against 'test.txt' and only allows file objects with that name to go through.
Get-ChildItem | where Length
In this case, the property it's looking for is Length (the file size) and there is no comparison given, so it's back to doing the "casting to true/false" thing from earlier. This will only show files with some content (non-0 length), and will drop 0 size files, for example.
ok, that brings me to your code:
Get-ChildItem | where(get-date).AddDays(-1)
With no {} and only one thing given to Where, it's expecting the parameter to be a property name, and is casting the value of that property to true/false to decide what to do. This is saying "filter where *the things in the pipeline have a property named ("09/08/2016 14:12:06" (yesterday's date with current time)) and the value of that property is 'truthy'". No files have a property called (yesterday's date), so that question reads $null for every file, and Where drops everything from the pipeline.
You can do as Jimbo answers, and filter comparing the file's write time against yesterday's date. But if you know the files and folders are named in date order, you can save -recursing through the entire folder tree and looking at everything, because you know what yesterday's file will be called.
Although you didn't say, you could do approaches either like
$yesterday = (Get-Date).AddDays(-1).ToString('MM-dd-yyyy')
Get-ChildItem "d:\receive\bhm\$yesterday\MBVOutputQueriesReport_C12_Custom.html"
# (or whatever date pattern gets you directly to that file)
or
Get-ChildItem | sort -Property CreationTime -Descending | Select -Skip 1 -First 1
to get the 'last but one' thing, ordered by reverse created date.
Read output from get-date | Get-Member -MemberType Property and then apply Where-Object docs:
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | `
Where-Object {$_.LastWriteTime.Date -eq (get-date).AddDays(-1).Date}
Try:
where {$_.lastwritetime.Day -eq ((get-date).AddDays(-1)).Day}
You could pipe the results to the Sort command, and pipe that to Select to just get the first result.
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | Sort LastWriteTime -Descending | Select -First 1
Can do something like this.
$time = (get-date).AddDays(-1).Day
Get-ChildItem -Filter "MBVOutputQueriesReport_C12_Custom.html" -Recurse -Path D:\BHM\Receive\ | Where-Object { $_.LastWriteTime.Day -eq $time }

PowerShell: return the number of instances find in a file for a search pattern

I have a text file with the following contents:
something
another something
stuff
more stuff
Using PowerShell, I have a script that searches for the pattern "something". This pattern will appear at most once per line on the file. I am trying to determine the number of times that this search pattern was found in the file (i.e., the number of lines that contain this pattern). I am using the following script:
$something_list = Select-String -Path $some_path -Pattern "something" | Select-Object Line
I then run the following command to get the number of elements in the Line property:
$n = $something_list.Length - 1
The problem I'm having is that this works if there are 2+ instances of "something" in the file. If there is only 1 instance of "something" in the file, $something_list.Length is meaningless, since Length can't be referenced for Line objects with only 1 element in them.
How can I resolve this?
you can use the Measure-Object cmdlet to select the count:
Select-String -Path $some_path -Pattern "something" | Measure-Object | select -expand count