How to Delete Outlook Item in Archive.pst - powershell

I'm stucked, i'm able to connect a pst file in Outlook, I would like to loop through all folders / search a certain email with a certain subject and then, delete it. I've searched through the web but don't know how to start, can someone explain me plz ? I'm lost with $namespace.folders.item.
Clear-host
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
$Namespace = $Outlook.GetNameSpace("MAPI")
$folders = "C:\Tools\Archive.pst"
$namespace.AddStore($folder)
I'm thinkin' about this but I know i'm wrong :
$email = $folders.Folders.items | Where-Object {$_.Subject -like "*alert*"} OR
Foreach ($Folder in $SubFolder.Folders)
{
$ItemsToDelete = $Folder.Items | Where-Object -Property subject -like "*alert*"
foreach ($item in $ItemsToDelete)
{
$item.Delete()
}
}
(all articles at Microsoft's are related to VB which I don't know and i'm starting Powershell : https://learn.microsoft.com/en-us/office/vba/api/outlook.namespace.addstore)
Thx for your advices.

After adding a new store in Outlook you can find it in the Stores collection which you may get by using the Stores property of the Namespace class. Use the Stores and Store objects to enumerate all folders and search folders on all stores in the current session. The following VBA sample code shows how you can use these objects to iterate over all stores and folders in Outlook:
Sub EnumerateFoldersInStores()
Dim colStores As Outlook.Stores
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
On Error Resume Next
Set colStores = Application.Session.Stores
For Each oStore In colStores
Set oRoot = oStore.GetRootFolder
Debug.Print (oRoot.FolderPath)
EnumerateFolders oRoot
Next
End Sub
Private Sub EnumerateFolders(ByVal oFolder As Outlook.Folder)
Dim folders As Outlook.folders
Dim Folder As Outlook.Folder
Dim foldercount As Integer
On Error Resume Next
Set folders = oFolder.folders
foldercount = folders.Count
'Check if there are any folders below oFolder
If foldercount Then
For Each Folder In folders
Debug.Print (Folder.FolderPath)
EnumerateFolders Folder
Next
End If
End Sub
Note, the Outlook object model is common for all programming languages, so you may find the sequence of property and methods calls in the sample shown above.
To find items that correspond to your conditions you need to use the Find/FindNext or Restrict methods of the Items class. In that case you will get only items that correspond to the search criteria and then you can iterate over them only. Read more about these methods in the articles I wrote for the technical blog:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
If you need to find items in multiple folders I'd recommend choosing the AdvancedSearch method of the Application class instead. The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
You can stop the search process at any moment using the Stop method of the Search class.
See Advanced search in Outlook programmatically: C#, VB.NET for more information.

Related

Powershell Set Unread flag for Outlook Desktop emails

I am trying to read emails from a folder in Outlook Desktop using powershell, and I can do that with the code below.
But is there any way by which I could also set the Unread property to $False for those emails
directly in outlook ? ( not in the objects stored in variables )
Browsing the website I found this: https://stackoverflow.com/a/34161683/13568461 which says to use MailItem.Save but I cant figure it out how to update my code to make use of that.
Much appreciated if anyone can help with that piece of code. Thank you in advance
Add-Type -assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -comobject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")
$Folder_AI = $namespace.Folders.Item('user#domain').Folders.Item('AI-ServiceDesk-Servers')
$Count_ItemsUnread = $Folder_AI.UnReadItemCount
$All_Folder_Items = $Folder_AI.Items | Select-Object -Property UnRead, Body
$All_Folder_Items | ForEach-Object {
$Email_Status = $PSItem.Unread
$Email_Body = $PSItem.Body
$Email_Status
}
But is there any way by which I could also set the Unread property to $False for those emails directly in outlook ? ( not in the objects stored in variables )
No, you need to get an item to set up a property. The Save method is required to make changes permanent and avoid any dialogs for saving changes made programmatically in Outlook.
When dealing with Exchange accounts in Outlook you may reach the limit of concurrently opened items if you iterate over all items in the folder/store. That is why Find/FindNext or Restrict methods are recommended. They allow getting items that correspond to your search criteria and iterate over them only. Read more about these methods in the article that I wrote for the technical blog:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder

Create new pst file if current file size reaches 2 GB

I want to schedule a Powershell script that checks the size of current pst file daily. If it reaches 2 GB I want to create a new pst file and make it default. Able to get the pst file location as below.
But 1. how to identify current pst file
2. how to create new pst file and make it default.
$outlook = New-Object -comObject Outlook.Application
$final=$outlook.Session.Stores | where { ($_.FilePath -like '*.pst')} | select FilePath
$final
To get the default store you can use the NameSpace.GetDefaultFolder to get any default folder. Then you can use the Store property of the Folder class which returns a Store object representing the store that contains the Folder object.
The Outlook object model doesn't provide anything for changing the account settings (like stores). You need to use a low-level API (Extended MAPI) or any other third-party wrappers around that API. But you can add a new store by using the AddStore or AddStoreEx methods of the Namespace class.
Sub CreateUnicodePST()
Dim myNameSpace As Outlook.NameSpace
Set myNameSpace = Application.GetNamespace("MAPI")
myNameSpace.AddStoreEx "c:\" & myNameSpace.CurrentUser & "\.pst",olStoreUnicode
End Sub

Invoke verb on multiple files via Shell.Application

I'm using "Shell.Application" COM object for some automation via PowerShell and I'm stuck on situation where I need to invoke verb on multiple items in folder. Basically I need to simulate situation where user selects multiple files/folders and calls verb from shell menu.
I can do it without any problem on single item, but I haven't found method how to call it on multiple items. Any idea how to do it?
Edit:
This is how I call it on single item:
$shell = New-Object -Com "Shell.Application"
$shell.Namespace($Path).Self.InvokeVerb("some action")
You can use InvokeVerbEx to execute on all files in a folder:
$shell.Namespace("C:\test").Items().InvokeVerbEx()
For particular files in a folder, I would think the best way is to put the single item code that you have in a loop:
$path1, $path2 | %{ $shell.Namespace($_).Self.InvokeVerb() }
The Filter method may be of use too

Powershell and Lotus Notes - How to extract user names with employees numbers?

I have specific problem. I need to extract domain names from active directory and combine them with employees numbers which are in Lotus Notes. I get the domain names with Get-QADUser (snapin from quest.com), that was no problem, but how to get the employees numbers and combine them? Thank you
Edit(18.5. 11:56): Now I'm using this script (posted by Christian) and I figured out how to get the name of LN database - right-click on DB in Lotus notes workspace, then application/properties.
# Create LN Object
$DomSession = New-Object -ComObject Lotus.NotesSession
# Initialize LN Object
# You'll be asking for LN password to your id
$DomSession.Initialize()
# Connect to Server, select db and display the name
$DomDatabase = $DomSession.GetDatabase("LN007","IT\HW.nsf")
Write-Host "Database open : " $DomDatabase.Title
# Open specific View (By Serial Number)
$DomView = $DomDatabase.GetView('Serial Number')
Write-Host "View read : " $DomView.Name
# Show number of documents
$DomNumOfDocs = $DomView.AllEntries.Count
Write-Host "Num of Docs : " $DomNumOfDocs
# Get First Document in the View
$DomDoc = $DomView.GetFirstDocument()
If you have access to the database and a Notes client, you can open the database in Notes Designer and review what views are available. You should then be able to find one or create one that contains the data you need.
If you don't have access to Lotus Notes, you're close enough with your powershell script that you can use the com API to get the information. The NotesDatabase object (i.e. $DomDatabase) has a Views property which will return NotesView objects. You can iterate over those and print out the names as a start. Likewise once you've found the view you want, you can access the columns within that view using the NotesView's Columns property.
You'll want to check out the COM api docs here for more help: http://blagoevgrad.court-bg.org/help/help85_designer.nsf/Main?OpenFrameSet (see the section LotusScript/COM/OLE Classes)
Depending on how comfortable you are with Powershell vs the com api, you could probably handle this a few ways, either by extracting all the documents in the view and getting the data out, or perhaps using the built in NotesView.GetDocumentByKey method that would act as a lookup in your script. With a view sorted on the key you're querying on (and set as your view's first column), you could call that method and get back the document with that key. Then use that NotesDocument object to retrieve any value within it (i.e. the employee name or number or whatever)
You can retrieve data from Lotus Notes using com object.
Suggested links:
http://davidmoravec.blogspot.it/2008/08/retrieve-data-from-lotus-notes-with.html
Lotus Notes comobject
Is the database you are opening called "names.nsf" by any chance? If so, that's the standard Domino Directory database and you should be using the "People" view, and the item name you are looking for should be "EmployeeID" -- unless the customer has customized the database with their own field names.
If it is a custom database you are working with, then in addition to using the Notes client and Domino Designer, get yourself a copy of NotesPeek. It's free. Download here
It gives you a tree view of the database. It shows you everything that is stored in the database -- but it only shows you what is stored, so computed fields that you can see in the Notes client but aren't accessible through the Notes classes won't confuse you. (The document properties dialog in the Notes client won't show you computed values either if you use it while you have a document selected in a view, but it will show them to you if you use while you have a document actually open.)

Add a "Hyperlink" item type to a list using PowerShell in Sharepoint

I've been a SharePoint admin for a while, and now have been tasked with a bit more of a developer role - which I'm still very much learning. Most things I've been able to figure out on my own or through Google, but this one has me stumped.
For one particular task I need to use PowerShell to script adding items to a list. Normally - not a difficult task. These steps are all over the web. However, I have yet to find anywhere that will tell you how to add a "Hyperlink" type of item to a list.
I can add one using the following code:
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = $($url.url)
$NewItem.Update()
But I want to set the name/title of the link as well and that's what stumps me. I don't want to have to create a separate column in the list and populate that with the link name, and use code similar to above to populate the url/link.
Does this work for you? I don't have a Sharepoint install available to test on, this is from memory:
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = "$($url.url), <Title>"
$NewItem.Update()
james
Thanks James! That was very close and I'm thinking would work if I was specifying a single item?
Here's my full solution (with some extra bits):
$enumsite = new-object microsoft.sharepoint.spsite($SubWebUrl)
foreach ($url in $enumsite.allwebs)
{
$NewItem = $MyList.Items.Add()
$NewItem["My Hyperlink Column"] = "$($url.url), $(url.title)"
$NewItem.Update()
}
$enumsite.Dispose()
Perhaps this will help someone else out in the future.