I have a simple one line command that list contents of some remote share
Get-ChildItem -Path "\\some_path\" -Recurse | Where-Object{ $_.LastWriteTime -lt (Get-Date).AddDays(-1) }
I need to send an email in case there are no files in this folder.
So I found code that should send an email:
if ($Condition) {
Send-MailMessage -From "sender#example.com" -To "receiver#example.com" -Subject "Condition met" -Body "The condition you specified has been met." -SmtpServer "smtp.example.com"
}
However, I'm not sure how should I define this $Condition in case there is nothing in this folder.
Maybe something like this:
$Condition = Get-ChildItem -Path "\\some_path\" -Recurse | Where-Object{ $_.LastWriteTime -lt (Get-Date).AddDays(-1) } | length>0
Thanks.
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
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...
}
I've whipped up a script that deletes old video directories, and it will create a log of what has been deleted in a .txt file.
Running the script on my Windows 7 PC, the .txt file in Notepad puts each output on a new line.
Running the script on my Windows 2012 Server, the .txt file in Notepad puts the output on the same line. If I open the log file with Wordpad, the outputs are on new lines.
Here's what the powershell script looks like:
$limit = (Get-Date).AddDays(0)
$logFile = "C:\BodyCam\bodycamlog.txt"
$output = "The following directories contain incorrect video dates" + "`n"
#Throw a timestamp on the log file
Add-Content -Path $logFile "=======$(Get-Date)======="
#Get all of the paths for each camera
$paths = Get-ChildItem -Path "D:\Videos\" |Select-Object -ExpandProperty FullName
#for each path we found
foreach ($pa in $paths) {
# Delete directories older than the $limit.
$dir = Get-ChildItem -Path $pa -Recurse -Force | Where-Object { $_.PSIsContainer -and $_.CreationTime -lt $limit }
$dir | Remove-Item -Recurse -Force
$dir | Select -Expand FullName | Out-File $logFile -append
if ($dir -match "1970"){
$output += $pa + "`n"
}
}
Send-MailMessage -to "Ray <***>" -from "BodyCamScript <***>" -subject "Bad Bodycam Date Found" -body $output -SmtpServer ***
What's the deal here?
The default encoding for Add-Content is ASCII, but the default for Out-File is Unicode. Use the encoding parameter on both to force the same encoding and it should work as you expect.
I would add this to my other post, but I can't find it. I have been trying to copy images (JPG and JPEG) from one UNC (source) to two UNCs (destinations) that are three days old. I only need to copy the images, not the folders they are contained in.
I do not get any errors, the email received from the script tells me no images were copied. The destinations do not have any images copied to them and there are images in the source that are newer than three days from todays date. I am completely lost. I have been on Google all day trying to figure this out to no avail so far. Any suggestions would be appreciated.
$ImageLocation = "\\vdifiles\Print-Room\FileSrv\Barcode-Order"
$TestSite = "\\10.0.100.3\www2.varietydistributors.com\catalog\newpictures"
$LiveSite = "\\10.0.100.3\Variety Distributors.com\catalog\newpictures"
$WhenFileWritten = (get-date).AddDays(-3)
$IncludeFileTypes = "*.jpeg,*.jpg"
$LogFile = "C:\Temp\FilesCopied.log"
$EmailServer = "emailserver.me.com"
$EmailFrom = "fromme#me.com"
$AuthUser = "user"
$AuthPass = "pass"
$XHeaderInfo = "X-Header: This email was sent from Laservault."
$EmailTo = "tome#me.com"
$EmailSubject = "Barcode Images Summary."
$EmailBodySent = "Attached to this email is a log file of what images were copied from $ImageLocation to $TestSite and $LiveSite as well as sent to AS2 to send over to Order Stream."
$EmailBodyNotSent = "There were no files in $ImageLocation that matched $WhenFileWritten days old. So, nothing was sent to $TestSite, $LiveSite or AS2."
$TheImages = get-childitem "Microsoft.PowerShell.Core\FileSystem::$ImageLocation" -recurse | where-object {$_.Extension -eq $IncludeFileTypes -and $_.LastWriteTime -gt $WhenFileWritten -and $_.PsIsContainer -eq $false}
foreach ($Images in $TheImages) {
$FileCount = $Images.count
if ($FileCount -gt 0) {
copy-item -path $Images.FullName -destination "Microsoft.PowerShell.Core\FileSystem::$TestSite" -force
copy-item -path $Images.FullName -destination "Microsoft.PowerShell.Core\FileSystem::$LiveSite" -force
write-host "$FileCount files were copied."
write-output $Images >> $LogFile
\\vdifiles\blat$\blat.exe -attach $LogFile -to $EmailTo -s $EmailSubject -i $EmailFrom -body $EmailBodySent -server $EmailServer -u $AuthUser -pw $AuthPass -f $EmailFrom -x $XHeaderInfo
remove-item $LogFile
} else {
\\vdifiles\blat$\blat.exe -to $EmailTo -s $EmailSubject -i $EmailFrom -body $EmailBodyNotSent -server $EmailServer -u $AuthUser -pw $AuthPass -f $EmailFrom -x $XHeaderInfo
}
}
Your original post: Copy-Item : Cannot bind argument to parameter 'Path' because it is null
I copied my answer from there here:
The issue is with the Get-ChildItem not returning anything. It's a small problem because of the -include and -exclude parameters you are feeding into it. You are defining the variable like this:
$IncludeFileTypes = "*.jpeg,*.jpg"
$ExcludeFileTypes = "*.psd,*.tif,*.pdf"
The problem is that the -include and -exclude parameters are expecting a string array (String[]) what you are giving them is a straight string.
We can prove this, if you create a file with the name "a.jpeg,a.jpg", the get-childitem cmdlt will return the file.
The solution is to change your $IncludeFileTypes and $ExcludeFileTypes variables to a string array, and it should return the results that you are expecting:
$IncludeFileTypes = "*.jpeg","*.jpg"
$ExcludeFileTypes = "*.psd","*.tif","*.pdf"
The where-object is not finding any match for any files.
Amend $IncludeFileTypes = "*.jpeg,*.jpg" to $IncludeFileTypes = #("*.jpeg","*.jpg")
Then pass that array of file types into the get-childitem command using the -include Parameter (-filter only takes one filetype, as a string) and remove the $_.Extension check from the where-object command.
e.g.
$TheImages = get-childitem "Microsoft.PowerShell.Core\FileSystem::$ImageLocation" -recurse -include $IncludeFileTypes | where-object {$_.LastWriteTime -gt $WhenFileWritten -and $_.PsIsContainer -eq $false}
You are also checking the count of the wrong variable to get your file count, and it shouldn't be inside the foreach loop.
Get the file count, then if it's greater than zero, iterate through the list if files, copying them.
Try:
$FileCount = $TheImages.count
if ($FileCount -gt 0) {
foreach ($Images in $TheImages) {
And also
write-output $TheImages >> $LogFile
Instead of
write-output $Images >> $LogFile
You are declaring the list wrong, it should be like this:
$IncludeFileTypes = #("*.jpeg","*.jpg")
Try searching with the -Include like this:
$TheImages = get-childitem "Microsoft.PowerShell.Core\FileSystem::$ImageLocation" -recurse -Include $IncludeFileTypes | where-object {$_.LastWriteTime -gt $WhenFileWritten -and $_.PsIsContainer -eq $false}
And check if the variable is empty after that:
if($TheImages -ne $null)
{
#move...
#send email...
#etc
}
Hope this solves your issue.