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
Related
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...
...
...
...
$Servers = Get-content 'D:\utils\Backup\SBX servers.txt'
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup\*_DB.zip -Recurse -Force -File |Format-Wide| Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result
}
you were not far from the solution, but there are multiple problem with your syntax. First you should not "filter" (where-object), after "formating" (Format-wide).
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup*DB.zip -Recurse -Force -File | Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result | Format-Wide
}
you were missing the "underscore" in your filter too: "$." -> "$_."
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
My Current Code Is
Param(
[string]$filePath = "C:\",
[string]$logFileFind = "error.log",
[string]$logFileReplace ="ThisHasBeenReplaced.log"
)
($configFile = Get-ChildItem -Recurse -Force $filePath -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $false) -and ( $_.Name -like "*.config") }
It Works fine and gives me list of files i was wondering how i could go through these files and find and replace certain words for when I'm moving though environments and the path wont be the same. I'm very limited in my powershell knowledge and i tried adding this to the end of the script.
ForEach-Object{(Get-Content $configFile) -replace $logFileFind , $logFileReplace | Set-Content $configFile})
This didn't work and i was wondering if there was anyone out there who knew what i could do to make it work.
Thanks in Advance!
You always access $configFile in your foreach loop (which is probably an System.Array), not the actual element. Try this:
$configFile | foreach { (get-content $_.FullName -Raw) -replace $logFileFind , $logFileReplace | Set-Content $_.FullName }
Here is a full example:
Get-ChildItem -Recurse -force $filePath -ea 0 |
where { ($_.PSIsContainer -eq $false) -and ( $_.Name -like "*.config") } |
foreach {
(gc $_.FullName -raw) -replace $logFileFind , $logFileReplace | sc $_.FullName
}
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.