powershell list last log and insert body email - powershell

Hello i need to send the last .log and insert in $body with get-content
$Logpath = "D:\Script\"
$LastLog = Get-ChildItem $Logpath | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} | select-object Name -last 1
$fullpath = Write-Output $Logpath $LastLog
$body = Get-Content $fullpath | out-string
PS D:\Script\> Get-ChildItem $Logpath | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} | select-object Name -last 1
Name
----
test05.txt
$fullpath doesn't work and $body i don't know how put up..
thx 4 help im noob

I think this may help you:
$Logpath = "D:\Script\"
$yesterday = (Get-Date).AddDays(-1)
# this will get you a FileInfo object of the latest log file
$LastLog = Get-ChildItem $Logpath -File | Where-Object {$_.LastWriteTime -gt $yesterday} | Select-Object -Last 1
# the FileInfo object has a 'FullName' property
Write-Host "Reading file '$($LastLog.FullName)'"
# to get the content as a single string, use the '-Raw' switch
$body = Get-Content $LastLog.FullName -Raw
# to send this as email, have a look at the 'Send-MailMessage' cmdlet at
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-6
#basic example on 'Send-MailMessage'
Send-MailMessage -To "someone#example.com" -From "me#example.com" -Subject "Log $($LastLog.Name)" -Body $body

Related

If path does not exist, skip FOREACH

I have a question that I hope one of you can help me with.
The following script does its job, it sends the email of the folders that are older than 30 days.
I want to add 2 more features...
If the OwnerEmail.txt is not there or empty.. it will not send the email.
If there are not folders older than 30 days, it will not send the email.
I am just having problems using the CONTINUE feature to skip the ForEach
$ParentFolders = Get-ChildItem -Path "C:\Test\WRA" -Directory |
Select-Object -ExpandProperty FullName
foreach ($SubFolder in $ParentFolders) {
$Contact = Get-Content -Path ($SubFolder + "\OwnerEmail.txt")
$emailTime = (Get-Date).ToString("MM/dd/yyyy")
$WRAHTMLReport = Get-ChildItem -Path $SubFolder -Directory |
Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-30))} |
Select-Object Name, CreationTime |
ConvertTo-Html -Head $Header -PreContent "
<h2>Current Nuix Case(s)</h2>
<body>
Report was sent on $emailTime
<br></br>
When you have a moment can you please confirm if any of these cases can be removed from Nuix:
<body>
<br></br> " |
$WRAHTMLReport = $WRAHTMLReport -join ""
Start-Sleep -s 2
Send-MailMessage -SmtpServer mail.company.com -to $Contact -from cubam1#company.com -Subject "Nuix Cases" -Body $WRAHTMLReport -BodyAsHtml
}
So, it could look something like this, note that I'm only showing the relevant parts of the code.
I think in this case, is safe to put the $emailTime outside the loop since you're only gathering the date in MM/dd/yyyy format and, I also added the $folderLimitDate outside the loop.
This variable contains the HTML body
$mailBody = ConvertTo-Html -InputObject $WRAHTMLReport... so remember to change the -Body $mailBody on Send-MailMessage
$emailTime = (Get-Date).ToString("MM/dd/yyyy")
$folderLimitDate = (Get-Date).AddDays(-30)
foreach ($SubFolder in $ParentFolders)
{
$path = Join-Path $SubFolder -ChildPath 'OwnerEmail.txt'
# If OwnerEmail.txt doesn't exist on this path,
# go to next loop iteration
if(-not(Test-Path $path)){ continue }
$Contact = Get-Content $path
$WRAHTMLReport = Get-ChildItem -Path $SubFolder -Directory |
Where-Object LastWriteTime -LT $folderLimitDate |
Select-Object Name, CreationTime
# If this variable is null, go to next loop iteration
if(-not $WRAHTMLReport){ continue }
[string]$mailBody = ConvertTo-Html -InputObject $WRAHTMLReport...
...
...
...

PowerShell - Return value from source CSV to CSV if value in column X exist

I never wrote a PowerShell script before, so I created the next script with the help of many different google searches :) so it might be a little patchy, I am by no means a "scripter"
To sum up I need to create a report of emails sent by specific mailboxes and return the data into Excel with this headers: time sent, sender, display name, recipients, subject.
I need help with adding the display name from the $output file
This is the what I created so far:
#Variables:
$output = "C:\temp\Source.csv"
$Unfiltered = "C:\temp\ReportUnfiltered.csv"
$UnfilteredV2 = "C:\temp\ReportV2.csv"
$CSVreport = "C:\temp\ReportV3.csv"
$finaleReportX = "C:\temp\finalReport.xlsx"
$To = "user#domain.com"
$desiredColumns = 'Date','Time','Sender','DisplayName','Recipients','MessageSubject'
#Create Source file:
get-mailbox -resultsize unlimited | where {$_.primarysmtpaddress -like "sales*"} | Select #{N='primarysmtpaddress';E={$_.primarysmtpaddress[0]}},displayname | export-csv $output -NoTypeInformation
$query = Import-Csv -Path $output
#Create Report for sent:
foreach ($Address in $query) {
Get-MessageTrackingLog -server exchange.domain.com -Start (get-date).addhours(-24) -end (Get-Date) -sender $Address.primarysmtpaddress |
where-object {$_.EventID -eq ‘RECEIVE’} |
Select Timestamp,sender,#{Name='Recipients';Expression={[string]::join(“;”, ($_.Recipients))}},MessageSubject,MessageID |
export-csv $Unfiltered -NoTypeInformation -encoding utf8 -Append
}
#Fix Timestamp:
Import-Csv $Unfiltered |
Select-Object *,
#{n='Date';e={$_.Timestamp.Split(" ")[0]}},
#{n='Time';e={$_.Timestamp.Split(" ")[1]}} |
export-csv $UnfilteredV2 -NoTypeInformation -encoding utf8
# Selects desired columns
Import-Csv $UnfilteredV2 | Select $desiredColumns |
Export-Csv -Path $CSVreport –NoTypeInformation -encoding UTF8
# Export to Excel
Import-Csv $CSVreport | Select $desiredColumns |
Export-Excel -Path $finaleReportX | Format-Table –AutoSize
#Send Final Report:
$email = #{
From = "Report#domain.com"
To = $To
subject = “Report for All sent items"
SMTPserver = "exchange.domain.com"
Body = "See the attached Report"
Attachment = $finaleReportX
}
send-mailmessage #email
# Delete Reports From Local Drive
Remove-Item –path $output –recurse
Remove-Item –path $Unfiltered –recurse
Remove-Item –path $UnfilteredV2 –recurse
Remove-Item –path $CSVreport –recurse
Remove-Item –path $finaleReportX –recurse
You are creating a lot of in-between csv files and load them back in. I don't think this is necessary if you combine all queries in a single ForEach-Object{} loop with a foreach() loop inside that.
Also, because of copy/paste from the internet, there were some curly 'smart-quotes' in the code (“, ”). Lots of times, PowerShell can handle that, but it is always better to use straight quotes " and ' in code.
Something like this:
# Variables:
$to = 'user#domain.com'
$from = 'Report#domain.com'
$smtpServer = 'exchange.domain.com'
$finaleReportX = 'C:\temp\finalReport.xlsx'
$today = Get-Date
$yesterday = $today.AddHours(-24)
# Create Report for email. Gather everything in a variable
$result = Get-Mailbox -Resultsize Unlimited |
Where-Object {$_.primarySmtpAddress -like "sales*"} |
ForEach-Object {
$emailAddress = #($_.primarySmtpAddress)[0]
$displayName = $_.DisplayName
$trackingLog = Get-MessageTrackingLog -Server exchange.domain.com -Start $yesterday -End $today -Sender $emailAddress |
Where-Object {$_.EventID -eq 'RECEIVE'}
# loop through the items in the tracking log and create objects from that
$trackingItems = foreach ($item in $trackingLog) {
$date, $time = $item.Timestamp -split ' '
# output an object with the desired properties to be collected in variable $trackingItems
[PsCustomObject]#{
Date = $date
Time = $time
DisplayName = $displayName
Sender = $item.Sender
Recipients = $item.Recipients -join ';'
MessageSubject = $item.MessageSubject
# MessageID = $item.MessageID # usure if you want this in your report aswell..
}
}
# output the in-between results to be collected in variable $result
$trackingItems
}
# Export to Excel file
$result | Export-Excel -Path $finaleReportX -Title 'Email tracking log' -AutoSize
# Send Final Report:
$email = #{
From = $from
To = $to
Subject = 'Report for All sent items'
SMTPserver = $smtpServer
Body = 'See the attached Report'
Attachments = $finaleReportX
}
Send-MailMessage #email
# Delete Report From Local Drive
Remove-Item -Path $finaleReportX

Outputting file list with linebreaks to Microsoft Teams

we are trying to get a file-list with certain filtering to our technical support department on Microsoft Teams.
Technically it works, but the output is messed up. For some reason it is not possible for me to get the files as a list to Teams. Instead, all files are just pasted in one large string with spaces between the filenames.
I've tried some formatting options, but couldn't get anywhere closer to a solution.
$Limit = (Get-Date).AddMinutes(-15)
$Path = "C:\Users\<username>\Desktop"
$Extension = "*.*"
$Results = #()
$Results += Get-ChildItem -Path $Path -Filter $Extension -Recurse -Force | Where-Object {$_.CreationTime -lt $Limit -and ! $_.PSIsContainer -and $_.Extension -ne ".db"} | Select-Object Name -ExpandProperty Name | Sort-Object Name
Invoke-RestMethod -Method Post -ContentType "Application/Json" -Body "{'text': '$Results'}" -Uri https://outlook.office.com/webhook/<deleted for this example...> | Out-Null
What I would like to get in Teams : a list with one filename per line
What I get now in Teams : One long string with filenames separated with a space.
Thank you in advance for any help :-)
You need to add a line break to each item in the array which in Teams I believe is 3 spaces and \n
That would look like this:
$Limit = (Get-Date).AddMinutes(-15)
$Path = "C:\Users\<username>\Desktop"
$Extension = "*.*"
$Results = #()
$Results += Get-ChildItem -Path $Path -Filter $Extension -Recurse -Force | Where-Object {$_.CreationTime -lt $Limit -and ! $_.PSIsContainer -and $_.Extension -ne ".db"} | Select-Object Name -ExpandProperty Name | Sort-Object Name
$Results = $Results | Foreach-Object {"$_ \n"}
Invoke-RestMethod -Method Post -ContentType "Application/Json" -Body "{'text': '$Results'}" -Uri https://outlook.office.com/webhook/<deleted for this example...> | Out-Null
If that doesn't work you may need to Loop through your array and add <br> to the end of each object but you will need to add <pre></pre> to apply HTML formatting.
That looks like this: (I tested this with Send-MailMessage -BodyAsHtml worked flawlessly)
$Limit = (Get-Date).AddMinutes(-15)
$Path = "C:\Users\<username>\Desktop"
$Extension = "*.*"
$Results = #()
$Results += Get-ChildItem -Path $Path -Filter $Extension -Recurse -Force | Where-Object {$_.CreationTime -lt $Limit -and ! $_.PSIsContainer -and $_.Extension -ne ".db"} | Select-Object Name -ExpandProperty Name | Sort-Object Name
$Results = $Results | Foreach-Object {"$_<br>"}
Invoke-RestMethod -Method Post -ContentType "Application/Json" -Body "{'text': '<pre>$Results</pre>'}" -Uri https://outlook.office.com/webhook/<deleted for this example...> | Out-Null
Let me know if any of these work out for you!
the first solution you've posted was the correct one !
Thank you so much for your quick help. I've tried similar options with
`n, but Teams did not accept that as a valid line break.
I owe you a cold pint of beer :-)
Sincerely,
Ruud

Powershell How to get lastwritetime file and log it

I have tried with powershell to check if files in a directory with subfolders do not have a changeover time of 10 hours (LastWriteTime).
If this is the case I would like to log its name and directory in a log.txt file and have an email alert.
So I did that, but it does not really work well ... below any help is appreciated!
$directories ='C:\folders'
$Logfile = "C:\log.txt"
function logit($msg){
$msg='[{0}]{1}' -f [datetime]::Now, $msg
$msg|Out-File $logfile -append
}
if([datetime]::Now - (Get-Item $directories).LastWriteTime -gt
[timespan]'0:10:0:0'){
Send-MailMessage -to "name <name#domain.com>" -from "name
<name#domain.com>" -subject "object" -smtpserver "smtp.domain.com" ..
Out-File $Logfile
Write-Host
}
Thank you
I try this, i get the good result. i'ts possible to modify "comparedate" in hours ?
$compareDate = (Get-Date).AddDays(-1)
#(Get-ChildItem -Path C:\temp\*.* -Filter '*.*' -Recurse | Where-Object {
$_.LastWriteTime -gt $compareDate})
try this:
$compareDate = (Get-Date).AddHours(-10)
Get-ChildItem "C:\temp\" -Recurse -file | Where LastWriteTime -gt $compareDate

Select-String is taking too long. How can I optimize it

I am really trying to speed this script up. I have a directory with about 17k files in it:
$date= Get-Date -Format yyyyMMdd
$dir= "C:\test\$date"
$path=Get-ChildItem -Path $dir -Recurse
$pattern = "<RESULT>FAILED</RESULT>"
$submitted = (select-string -path $path -pattern $pattern | measure-object).Count
select-string -path $path -pattern $pattern | select Path,Filename,Line | Export-Csv -Path "D:\Failed.csv"
if($submitted -eq 0) {
Remove-Item "D:\Failed.csv" -recurse
}
else
{
Send-MailMessage -From "noreply#email.com" -To users#email.com -Subject "Failed Report" -Body "Attached are the failed files. This is for the last 3 hours. There may be files that were already reported." -Attachments "D:\Failed.csv" -SmtpServer 0.0.0.0
Remove-Item "D:\Failed.csv" -recurse
}
If Select-String is taking a long time in the script above, try only doing it once. Also, I see that you check the count and if nothing is going on, you delete that CSV you made. So howabout you count it first, and then only make it if you need to.
...
$submitted = select-string -path $path -pattern $pattern
...
if(($submitted | Measure-Object).Count -gt 0){
...make the csv using the $submitted variable as the source...
...send the csv...
...delete the csv...
}