Modify PowerShell script to attach not only .docx but also .html files - powershell

The script below uses Outlook to send emails with .docx attachments.
I would like to change the PowerShell script below to also add any .html files it finds, in addition to .docx files.
Any assistance in modifying this script is appreciated.
I would like to modify this PowerShell email script which uses Outlook so send an email with an attachment.
I want to include any .html files it also sees, in addition to the .docx file.
Thanks in advance to who may be able to assist me modify this.
#SendEMail $SendTo $MailSubject $htmlOutput
# Check to see we have all the arguments
If (Test-Path -Path "C:\Users\User1\Report\Report.html") {
$FullPath=$args[0]
#Get an Outlook application object
$o = New-Object -com Outlook.Application
$mail = $o.CreateItem(0)
#2 = High importance message
$mail.importance = 1
$mail.subject = "Report: $(get-date)"
$mail.HTMLBody = "Report $(get-date)`n$(Get-Content 'C:\Users\User1\Report\Report.html'
| Out-String)"
$mail.To = "email#emaildomain.com"
# Iterate over all files and only add the ones that have an .docx extension
$files = Get-ChildItem $FullPath
for ($i=0; $i -lt $files.Count; $i++) {
$outfileName = $files[$i].FullName
$outfileNameExtension = $files[$i].Extension
# if the extension is the one we want, add to attachments
if($outfileNameExtension -eq '.docx')
{
$mail.Attachments.Add($outfileName);
}
}
$mail.Send()
# give time to send the email
Start-Sleep 5
# quit Outlook
$o.Quit()
#end the script
#exit
}

It is not clear if also files from any subdirectories should be attached or not, but here's code for both scenarios:
Scenario 1: Only files from $FullPath, not from any subdirectories
# Iterate over all files and only add the ones that have a .docx or .html extension
$files = Get-ChildItem -Path $FullPath -File | Where-Object { '.docx', '.html' -contains $_.Extension }
foreach ($file in $files) {
$mail.Attachments.Add($file.FullName);
}
Scenario 2: All .docx and .html files from $FullPath AND its subdirectories
# Iterate over all files and only add the ones that have a .docx or .html extension
$files = Get-ChildItem -Path $FullPath -File -Recurse -Include '*.docx', '*.html'
foreach ($file in $files) {
$mail.Attachments.Add($file.FullName);
}
After this, you can send the email.
Note To stop consuming memory, you should release the COM objects:
$o.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($mail)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($o)
$null = [System.GC]::Collect()
$null = [System.GC]::WaitForPendingFinalizers()

Related

Powershell - How can I exclude All Files in the Get-childitem command and include Get-Adgroupmember

Still new to powershell and I am needing to do a security report and find all the permissions applied to all folders within a drive and then export it onto an excel document. The command I've got so far includes files but all the files are setup to inherit from the folder they are in. What im hoping to do is for it to ignore all the files that include .txt, .msg, .doc, .xlsx etc etc.
Also hoping with the groups it pulls in to use the Get-Adgroupmember on it so that I can see who is in the group and also export this to the excel file in the column next to it.
$FilePath = Get-childitem "\\C:\Downloads\TEST" -Recurse
ForEach ($File in $FilePath) {
$Acl = Get-Acl -Path $File.FullName
ForEach ($Access in $Acl.Access) {
$Properties = [ordered]#{'File Name' = $File.FullName; 'Group/User' = $Access.IdentityReference; 'Permissions' = $Access.FileSystemRights; 'Inherited' = $Access.IsInherited }
New-Object -TypeName PSObject -Property $Properties | Export-Csv "C:\Downloads\FinanceResult.csv" -append -NoTypeInformation
}
}

PowerShell Compress and Read-Only using Send-To

I am pretty new in PowerShell scripting so if what I am asking is not possible by all means tell me that.
I would like to create a PowerShell script that would accept the send-to command.
The purpose of the script is to change the files to read-only and then compress those files. I’d like to be able to select multiple files in file explorer then right-click, send to (Script)
Is this something that is possible? Thanks!
Update 1
Alright, I have it were it will select files using file explorer then pass them into the script. The read-only is functioning correctly. Just need to sort out the compression.
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property #{
Multiselect = $true # Multiple files can be chosen
Filter = 'Images (*.jpg, *.png)|*.jpg;*.png' # Specified file types
}
[void]$FileBrowser.ShowDialog()
$path = $FileBrowser.FileNames;
If($FileBrowser.FileNames -like "*\*") {
# Do something before work on individual files commences
$FileBrowser.FileNames #Lists selected files (optional)
foreach($file in Get-ChildItem $path){
Get-ChildItem ($file) |
ForEach-Object {
Set-ItemProperty -Path $path -Name IsReadOnly -Value $true
}
}
# Do something when work on individual files is complete
}
else {
Write-Host "Cancelled by user"
}
Update 2 Alrighty I got it all working, does what I need it too. Here it is if anyone has any interest in it.
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property #{
Multiselect = $true # Multiple files can be chosen
}
[void]$FileBrowser.ShowDialog()
$path = $FileBrowser.FileNames;
If($FileBrowser.FileNames -like "*\*") {
# Do something before work on individual files commences
$FileBrowser.FileNames #Lists selected files (optional)
foreach($file in Get-ChildItem $path){
Get-ChildItem ($file) |
ForEach-Object {
Set-ItemProperty -Path $path -Name IsReadOnly -Value $true
compact /C $_.FullName
}
}
# Do something when work on individual files is complete
}
else {
Write-Host "Cancelled by user"
}

Renaming child items after moving til another directory - powershell

I have been handed over a Powershell script that searches a folder for new items, if there are any items, it sends an email with the items attached and moves them to another directory. However, my problem is that the files in the first directory will always be named the same so i would need to rename the files as i move them to the back-up directory with date and time to prevent the older files from being overwritten. How would i go about the code to do so?
I should probably add that i have no experience with powershell, hence the probably stupid question.
$Folders = #( 'C:\Users\PAT\Desktop\attachement testfolder'
)
$DestFolder = 'C:\Users\PAT\Desktop\Backup folder'
$EmailList = #( 'recieving-email#hotmail.com'
)
$From = 'pat#email.com'
$Subject = 'New files'
$SMTPServer = '111.111.111.111'
# Get new files
$NewFiles = $Folders | Get-ChildItem -File -Recurse
# If there are an new files...
If ( $NewFiles )
{
# Add the file count and file names to the body of the email
$Body = '$($NewFiles.Count) new files attached'
$NewFiles | ForEach { $Body += $_.Name + "" }
# Send the email with attachments
Send-MailMessage -From $From -To $EmailList -Subject $Subject -Body $Body -
BodyAsHTML -Attachments $NewFiles.FullName -SmtpServer $SMTPServer
# Move the emailed files to the destination folder
$NewFiles.FullName | Move-Item -Destination $DestFolder -Force
}
Ended up figuring it out
I changed the Move-Item with this code
# Rename files with current date and time and moves them to backup directory
$NewFiles | ForEach-Object {
Move-Item -Path $_.FullName -Destination "C:\Users\PAT\Desktop\Backup
mappe\$($_.BaseName,(Get-Date).ToString("MMddyyyy hhmmss"),$_.Extension)"}
Also, as an alternative:
$NewFiles | Rename-Item -NewName { "$(Get-Date -Format "yyyyMMddHHmmss")-$($_.Name)" } -PassThru | Move-Item -Destination $DestFolder

Using powershell to batch convert docx to pdf

I'm attempting to use powershell to batch convert a lot of docx into pdf, into a different directory while maintaining the folder structure of the root.
I have the script working, however around 1 out of every 10 documents word pops up a "SaveAs" dialog, which i do not understand prompting me to save the docx file, although i have visible set to false.
#Stage the files
$sourceDir = "C:\Documents\"
$targetDir = "C:\Temp_Stage\"
Get-ChildItem $sourceDir -filter "*.doc?" -recurse | foreach{
$targetFile = $targetDir + $_.FullName.SubString($sourceDir.Length);
New-Item -ItemType File -Path $targetFile -Force;
Copy-Item $_.FullName -destination $targetFile
}
#Convert the files
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$folderpath = "c:\Temp_Stage\*"
$fileTypes = "*.docx","*doc"
Get-ChildItem -path $folderpath -include $fileTypes -Recurse |
foreach-object {
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
$doc = $word.documents.open($_.fullname)
$doc.saveas([ref] $path, [ref]$wdFormatPDF)
$doc.close()
}
$word.Quit()
Is there a way to suppress all word dialogs / warning / errors it should be a fairly automatic process that has ended up being pretty manual process.
I found out that you should pause between the Word-COM commands.
I also had to write a script that Word converts the documents from. dot to. dotm.
Not only did I occasionally get the save dialog, but also a lot of E_FAIL errors in the console.
The breaks (maximum 50ms) helped a lot.
Break in Powershell:
Start-Sleep -m 50
I hope it will help you.
Greetings
Bloodrayne1995

Extract a certain file from zip via Powershell seems like not to look in sub folders

I'm very new to Powershell and especially to Powershell and ZIP files. I would like to unzip a specific file from the passed zipfile. To do so I have the code below. The code below should get a *.update from the zip.
The issue I have is that the specific file is within another folder. When running the script it seems it won't look in the folder in the zip for more files.
I've tried the GetFolder on the $item and/or foreach through the $item. So far no success. Anyone an idea or an direction to look in to?
function ExtractFromZip ($File, $Destination) {
$ShellApp = new-object -com shell.application
$zipFile = $ShellApp.NameSpace($File)
foreach($item in $zipFile.Items())
{
Write-Host $item.Name
if ($item.GetFolder -ne $Null) {
Write-Host "test"
}
if ($item.Name -like "*.update") {
$ShellApp.Namespace($Destination).copyhere($item)
break;
}
}
}
Here's how you can do it natively in newer versions of Powershell:
Add-Type -Assembly System.IO.Compression.FileSystem
$zip = [IO.Compression.ZipFile]::OpenRead($sourceFile)
$zip.Entries | where {$_.Name -like '*.update'} | foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "C:\temp\test", $true)}
$zip.Dispose()
Solved it by using the script below:
Add-Type -Path 'C:\dev\Libraries\DotNetZip\Ionic.Zip.dll'
$zip = [Ionic.Zip.ZIPFile]::Read($sourceFile)
foreach ($file in $zip.Entries) {
if ($file -like "*.update") {
$zip | %{$file.Extract("C:\temp\test", [Ionic.Zip.ExtractExistingFileAction]::OverWriteSilently)}
}
}