Marking Emails as Read - powershell

I might be asking this in the wrong place so I apologize. I'm running a PS1 file to look in a specific folder, mark the emails as read, save the attachments and send me an email. For whatever reason, marking the emails as read, doesn't always work.
Since everything else works perfectly, I'll leave you with just what is not working
#Open Outlook and find emails from today
$ol = New-Object -ComObject Outlook.Application
$ns = $ol.GetNamespace('mapi')
$mb = $ns.Stores['some#email.com'].GetRootFolder()
$inbox = $mb.Folders['Reports']
$inbox.Items | ForEach-Object {$_.UnRead = $false}
If I run the script in ISE one line at a time, it works.
The problem arises when I select all and run in ISE, or as a PS1
Thanks!

Related

Parse .msg files to fetch To, from, subject and date using Powershell

I am trying to get To, From, subject, sent date from about a 100 .msg files that are saved in a folder on my local drive, possibly get all that info in a csv using powershell.
I ran this code I got from another post
Get-ChildItem "C:\--------\msgfileshere" -Filter *.msg |
ForEach-Object{
$outlook = New-Object -comobject outlook.application
$msg = $outlook.CreateItemFromTemplate($_.FullName)
$msg | Select From,to,subject,Senton,Cc|ft -AutoSize
}
I am able to get Subject and Senton date.
But no other information comes out related to Sender, to, Cc. Am I missing something here?
Edit: I was able to get Sender info which gives System.__ComObject as the output but not the actual email address

Powershell GUI Drag-and-Drop empty arg from email attachments

I have a GUI with a read-only textbox that I drag files to and a function then runs with the file. This works on my machine for files in local download folders, all file extensions, outlook email attachments, etc. I have no issues.
A colleague has begun using it and he is unable to successfully drag email attachments from outlook into the box. The arg is empty. It all works on my machine, but not his. I had one other person test, and they had the same issue.
$filebox.Add_DragEnter({
if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop)) {
$_.Effect = [Windows.Forms.DragDropEffects]::Copy
}
})
$filebox.Add_DragDrop({
foreach ($file in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) {
create_dir $file # Function doesn't even trigger here with outlook email attachments because no arg
}
})
We are all pulling from a shared inbox. Nothing is hard-coded to identify the user, or define a set path, it should just grab the path of the arg dropped in the box, right?
I'm just confused how the drag/drop is working for some files but not email attachments, and then also working fully on my machine.
I would consider myself a pretty novice coder, and first time ever messing with Powershell. (I do not have access to anything else in this situation. No ability to compile c#, powershell is it.). Maybe I'm missing something fundemental here. Anyone have any thoughts on this?
File format wont be present since there is no physical file on the file system. see Upload fails when user drags and drops attachment from email client
$filebox.Add_DragDrop({
if ($_.Data.GetDataPresent([System.Windows.Forms.DataFormats]::FileDrop)) {
foreach ($file in $_.Data.GetData([System.Windows.Forms.DataFormats]::FileDrop)) {
create_dir $file
}
}
else {
$outlook = New-Object -ComObject Outlook.Application
$s = $outlook.ActiveExplorer().Selection
foreach ($item in $s){
foreach($a in $item.Attachments){
$name = Join-Path -Path $dlpath -ChildPath $a.filename
$a.SaveAsFile($name)
create_dir $name
}
}
}
})
As Dmitry noted, the files aren't actually saved on the machine so I can't just Copy-Item. Here, the file is saved, and then the create_dir function is called and it can copy the item from the new download path.

Reading a text file line by line

I'm new to power shell and can't seem to get this script correct.
$WshShell = New-Object -comObject WScript.Shell
$users = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users.txt'
$users1 = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users1.txt'
$Shortcut = $WshShell.CreateShortcut("\\Fssrv\homeshares$\$users1\$users.lnk")
$Shortcut.TargetPath = "\\asrv1\users\$users"
$Shortcut.Save()
Every time it goes to "users.txt" it tries to read it as a complete file. Instead i would like for it to read as followed:
User1
User2
User3
I just can't seem to get this to work.
RE-EDIT:
What I’m trying to accomplish:
We went from one storage server to a new storage server.
ASRV1 to FSSRV
I want to create a shortcut from asrv1 to fssrv. Along with the upgrade we are also changing domains and changing everyone windows user names.
For example my user name was fMunoz and it was changed to fMunoz00.
I want to pull from a text file > users.txt with all the old usernames, and create shortcuts to the new user names storage file those users names are in a txt file called users1.txt.
If I understand your request, you want to create shortcuts in each home directory of the people in Users1.txt
This means you will need to complete multiple ForEach loops to cycle through both txt files.
$WshShell = New-Object -comObject WScript.Shell
$users = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users.txt'
$users1 = Get-Content '\\fssrv\homeshares$\fMunoz00\Desktop\users1.txt'
# For every line in $users1, Do something
Foreach($User in $users1) {
# For every line in $users, Do something
Foreach($Name in $users) {
$Shortcut = $WshShell.CreateShortcut("\\Fssrv\homeshares$\$User\$Name.lnk")
$Shortcut.TargetPath = "\\asrv1\users\$Name"
$Shortcut.Save()
}
}
I want to thank everyone for helping me.
I came up with a different solution for my problem. The way i fixed this issue was by creating an excel sheet w/ 2 columns.
OLD USERS | NEW USERS
I then created a mail merge using microsoft word. Then i continued with the following code in powershell to start my loop:
$WshShell = New-Object -comObject WScript.Shell
Once my loop was started with i then utilized mail merge to take <> from the excel sheet and replaced it with the insert it into my code. Also took <> and did the same.
$Shortcut = $WshShell.CreateShortcut("\Fssrv\homeshares$\«New_Users»\«Old_Users»_Z Drive.lnk")
$Shortcut.TargetPath = "\asrv1\users\«Old_Users»"
$Shortcut.Save()
I hope this can help anyone else trying to accomplish something similar.
Yet again, Thanks & Good Luck...

Printing all Excel files in a folder using PowerShell

I have a PowerShell script that I wrote a few years ago and it worked great...until it didn't.
$shell = New-Object -com Shell.Application
$filepath = 'C:\Billing\Clients'
$shell.Namespace($filepath).Items() |
% { $_.InvokeVerb('Print') }
In the C:\Billing\Clients folder I copy ~100 Excel files. Each of these Excel files need to be printed, in the alphabetical order of the file name.
This was working great until this month. I guess an update to Excel changed things.
Now the script tries to open and print all of the Excel files at the same time. Previously it printed the files in serial.
This was awesome. Now it brings my system to it's knees and documents are printed in a random order.
Any ideas on how I can invoke the Print operation and wait for it to complete prior to calling the Print operation on the next file?
I have used this in the past to pull files into excel and print them. You will need to ensure your default print settings are set first or use $xl.ActivePrinter = "PRINTERNAME AS EXCEL SEES IT" to set it first.
#Open Excel
$xl = new-object -comobject excel.application
#don't show the window
$xl.visible = $false
#get all of your files
get-childitem "C:\SOME\Path" "*.xlsx" | foreach-object {
#open file
$wb = $xl.Workbooks.Open($_.FullName)
#print with defaults
$wb.PrintOut()
#close without saving any changes
$wb.Close($false)
}
#all done so close excel
$xl.Quit()

Programmatically Moving Emails Efficiently

I'm writing a script that moves all of my read emails older than 2 weeks to a separate PST for archiving. Once it is acceptable, I'll execute it via a rule.
However, my current code takes a very long time to complete (about 8 minutes), while simply doing a drag and drop in Outlook is phenomenally quicker.
Does anyone know of a better way to move large amounts of emails? Maybe via accessing Outlook's index?
Add-Type -AssemblyName "Microsoft.Office.Interop.Outlook"
$Outlook=New-Object -ComObject Outlook.Application
$Namespace = $Outlook.GetNameSpace("MAPI")
$Items=1
while ($Items -gt 0)
{
$Items=0
$SourceFolder = $Namespace.Folders.Item($SourcePSTName).Folders.Item($Folder)
$TargetFolder = $Namespace.Folders.Item($TargetPSTName).Folders.Item($Folder)
$AllOfDem=($SourceFolder.Items | where {$_.SentOn -lt $SentMaxDate -and $_.Unread -eq $False})
foreach ($Mail in $AllOfDem)
{
$Mail.Move($TargetFolder) | Out-Null
$Items++
}
}
I suspect your problem is not so much moving the messages (which can be optimized using Extended MAPI or Redemption (I am its author) to move all messages in a single call), but rather looping through all items in a folder - that is a huge problem.
Instead of looping, use Items.Find/FindNext or Items.Restrict to provide a query that only returns the matching items.