Powershell Check newest log file for latest entry containing error - powershell

I know I am missing something small. But, I am overlooking something. I want the script to look in a specific path for the newest log file, and check the last line of the log file, and if it contains a specific error, have it email a notification. It finds the newest file properly, but doesn't seem to be giving me the output of the last line. Thoughts on what silly thing I missed?
Set-Location -Path "\\COMPUTER\C$\application\logs"
$latest = Get-ChildItem | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$latest.name
$lastentry = Get-Content $latest | Select-object -last 1
if ($lastentry -like "ERROR: Access violation at address*") {
$strFromAddress = "monitoring#acertaindomain.com"
$strToAddress = "LotsOfPeople#acertaindomain.com"
$strMessageSubject = "Your log has errors"
$strMessageBody = "Bad stuff is happening"
$strSendingServer = "mail.acertaindomain.com"
}

I'm such an idiot. I thank you guys for the input. All those email tags and I completely forgot the actual command to send the bloody email.
I just brain farted in the worst way. But also, your added logic helped proof it. I of course realized I was jacking up something silly when write-output displayed what I was looking for.
Remember kids, it's all great to set variables. But don't forget to do something with them. lol

Related

Powershell - Get part of a file path up to a point from a CSV

Need some help with a substring please? I have a csv which contains file paths in column A.
These paths have .foo at the end (appended from the original query).
Is there a way to use a substring (or something else) which will search the path\text and return the content up until this point for example
C:\test folder\Folder1\Test 2\filename.abc(foo)
and return
C:\test folder\Folder1\Test 2\filename.abc
I dont really have any sample code as Im just starting out - thanks.
I am not going to write this for you but I will give you an example and some things to read to get you going. Make sure to take the tour https://stackoverflow.com/tour.
Jump in to your code by writing some code and then come ask again. These articles here will help you with what you want.
https://devblogs.microsoft.com/scripting/trim-your-strings-with-powershell/
or
https://adamtheautomator.com/powershell-split-path/
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_split?view=powershell-7.2
Here is an example I made for you
$file = (Get-ChildItem C:\Temp\dnd.txt | Select-Object -ExpandProperty name).Split('.')[0]
There are a ton of ways to do what you are asking and my example is not even a start. Write some code, define your goals and come ask again.
a different example
https://devblogs.microsoft.com/scripting/two-simple-powershell-methods-to-remove-the-last-letter-of-a-string/
$file = Get-ChildItem C:\Temp\dnd.txt | Select-Object -ExpandProperty name
$file = $file.Substring(0,$file.Length - 3)
$file
Corrected again. Please understand there are better ways to do what I did and you really need to explain what you want better.
Last one :)
Let's assume you have a file called example.csv in the c:\temp folder.
Inside the file example.csv are a bunch of paths with something you need to strip of the end and then output the results.
Contents of example.csv
head
c:\temp\fileafoo
c:\temp\filebfoo
c:\temp\filestuffcfoo
The code
$paths = $null
$paths = Import-Csv C:\temp\example.csv | ForEach-Object{
$var = $null
$var = $_.head
[PSCustomObject]#{
Corrected = $var.substring(0,$var.length - 3)
}
}
$paths
Results are
Corrected
---------
c:\temp\filea
c:\temp\fileb
c:\temp\filestuffc
And you can export this with $paths | Export-csv c:\temp\result.csv -NoTypeInformation

Using Where-Object to find files created within time range

all. I'm trying to take the creation date of a file in one folder and use it to filter files in another while also making sure they contain the phrase 'MS'. This is what I have so far:
$MSdat_time = $MSdat_file.CreationTime
# Defining maximum and minimum auto save creation times with a window of +/- 5 min
$auto_maxtime = ($MSdat_time).AddMinutes(5)
$auto_mintime = ($MSdat_time).AddMinutes(-5)
# Locating any Auto Save files created within time frame using 'MS' pattern as a parameter in case of multiple files
$autsav_file = Get-ChildItem "\\IP.Address\Test Data\Auto Saves" | `
Where-Object {($_.LastWriteTime -ge $auto_mintime) -and ($_.LastWriteTime -le $auto_maxtime)} | `
Select-String -Pattern 'MS' | Select-Object -Unique Path
I put in 'IP address' as a place holder. So far, it's returning nothing even though I know a file with those parameters exists and this section of code was working fine yesterday.
Check that your $MSdat_file variable has a value. It could be that your previous PS sessions had given that variable a value outside of your script.
After assigning $MSdat_file = Get-Item "./out.wav", I was able to get expected output:
PS /Users/ethansmith> /Users/ethansmith/Documents/test.ps1
PS /Users/ethansmith> $autsav_file
Path
----
/Users/ethansmith/Documents/test.ps1
Thank you everyone for your help! #ethan was right, the issue was with my $MSdat_file variable having an old value saved to it. Should have traced my code back to the beginning sooner haha. Thanks everyone!

Need assistance with PowerShell Script to clean up computers in AD that meet criteria

Hello & thanks in advance for the help!
Looking to delete computers (Workstations OU) in AD if they meet a certain criteria.
I need to make sure they have the "LOCATION," part of the Canonical name in common before proceeding to delete. If they are not at my location that could be reason to investigate and I do not want to delete them. This is an example of one PC (Caps are fields I changed):
ORGANIZATION.COM/Workstations/BUSINESS UNIT/Desktops/LOCATION/COMPUTER NAME
I have the following script currently that will print them to a .csv which is helpful, but to take it one step further, it would be nice to print this on the screen then review it quick and proceed with a delete. Any tips??
Get-Content C:\Temp\Powershell\hosts.txt | ForEach-Object {
Get-ADComputer $_ -Properties Name,CanonicalName |Select-Object Name,CanonicalName
} -ErrorAction Ignore | Export-Csv C:\Temp\Powershell\Output.csv
Or even a second line of code I can utilize the output.csv with, not sure where to go from here...
Again, Thanks!
Added -Recursive and it seems to be working as expected.

Read from randomly named text files

I'm finishing a script in PowerShell and this is what I must do:
Find and retrieve all .txt files inside a folder
Read their contents (there is a number inside that must be less than 50)
If any of these files has a number greater than 50, change a flag which will allow me to send a crit message to a monitoring server.
The piece of code below is what I already have, but it's probably wrong because I haven't given any argument to Get-Content, it's probably something very simple, but I'm still getting used to PowerShell. Any suggestions? Thanks a lot.
Get-ChildItem -Path C:\temp_erase\PID -Directory -Filter *.txt |
ForEach-Object{
$warning_counter = Get-Content
if ($warning_counter -gt '50')
{
$crit_counter = 1
Write-Host "CRITICAL: Failed to kill service more than 50 times!"
}
}
but it's probably wrong because I haven't given any argument to Get-Content
Yes. That is the first issue. Have a look at Get-Help <command> and or docs like TechNet when you are lost. For the core cmdlets you will always see examples.
Second, Get-Content, returns string arrays (by default), so if you are doing a numerical comparison you need to treat the value as such.
Thirdly you have a line break between foreach-object cmdlet and its opening brace. That will land you a parsing problem and PS will prompt for the missing process block. So changing just those mentioned ....
Get-ChildItem -Path C:\temp_erase\PID -Directory -Filter *.txt | ForEach-Object{
[int]$warning_counter = Get-Content $_.FullName
if ($warning_counter -gt '50')
{
$crit_counter = 1
Write-Host "CRITICAL: Failed to kill service more than 50 times!"
}
}
One obvious thing missing from this is you do not show which file triggered the message. You should update your notification/output process. You also have no logic validating file contents. The could easily fail, either procedural or programically, on files with non numerical contents.

Need to scan all domain computers for .pst files

I am new to powershell sctipting, like Brand new. I have some experience using Exchange powershell but thats always been for very specific items like adjust calendar permissions and such. Nothing to robust.
Currently I am working on a powershell script to push out via Group policy that will run a a search on each domain PC. I've been getting help from a co-worker but he isn't available right now and I have a hard time following him sometimes. I am this site and its user might be able to assist me. What I am trying to do(and I believe I am close to) is pulling a list of drives for each computer on the domain. Once I pull that list O pipe it into a variable and then do a search on that variable for any files that end with .pst. Once the search is complete if there were results from the search a file should be created with the FUllname"path" of each file and the computer name should be used for naming the file. If there are no results form the search the file would be empty but the filename should still be named after t he computer. I believe I have gotten everything correct except that I do not know how to name the file based on the computer name. Thank you for your time and help with this.
Here is my code so far:
$drives=Get-WmiObject -query "SELECT * from win32_logicaldisk where
DriveType = '3'" | select deviceid
foreach ($drive in $drives){
$pstfound=Get-ChildItem $drive.deviceid *.pst -recurse | select
fullname
$pst+=$pstfound
}
IF ($pst -eq $null) {
$pst | Out-File \\"Servername"\Searchresults\Null
} Else {
$pst | Out-File \\"Servername"\Searchresults\HasItems
}
Thank you. I wasn't initially planning on using the UNC path but changed it up anyways and I think that will make it easier to go through later. I also figured out my issue for naming the file generated after the computer it ran on. I just set a variable $hostname=hostname and then set the files as \$hostname.csv