Simple EWS Script to list items in a folder or Subfolder

$mailbox = Get-Mailbox %Usernameofmailboxtocheck%
$mailAddress = $mailbox.PrimarySmtpAddress.ToString();
 
[Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll") | Out-Null
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.AutodiscoverUrl($mailAddress);
 
$MailboxRootid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailAddress)
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)
 
# Get Folder ID from Path
Function GetFolder()
{
	# Return a reference to a folder specified by path
 
	$RootFolder, $FolderPath = $args[0];
 
	$Folder = $RootFolder;
	if ($FolderPath -ne '\')
	{
		$PathElements = $FolderPath -split '\\';
		For ($i=0; $i -lt $PathElements.Count; $i++)
		{
			if ($PathElements[$i])
			{
				$View = New-Object  Microsoft.Exchange.WebServices.Data.FolderView(2,0);
				$View.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
				$View.PropertySet = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly;
 
				$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $PathElements
 
[$i]);
 
				$FolderResults = $Folder.FindFolders($SearchFilter, $View);
				if ($FolderResults.TotalCount -ne 1)
				{
					# We have either none or more than one folder returned... Either way, we can't continue
					$Folder = $null;
					Write-Host "Failed to find " $PathElements[$i];
					Write-Host "Requested folder path: " $FolderPath;
					break;
				}
 
				$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s, $FolderResults.Folders[0].Id)
			}
		}
	}
 
	$Folder;
}
 
#Uncomment the two lines below if referencing a folder that is not in the WellKnownFolderNameList ( and Comment Third Line ) 
#$folderobject = GetFolder($MailboxRoot, "\Folder\Path\");
#$folderid = $folderobject.id
$folderid = new-object  Microsoft.Exchange.WebServices.Data.Folderid([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Tasks,$mailAddress)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$folderid)
 
 
$mails = $inboxFolder.FindItems(20) 
 
    foreach($Item in $mails.Items)
	{ 
 
Write-Host $item.InternetMessageId 
Write-Host $item.Subject
Write-Host $item.DueDate
 
	}
VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

 

set objShell = WScript.CreateObject("WScript.Shell") 
Set objFSO = CreateObject("Scripting.FileSystemObject")
appDataPath = objShell.ExpandEnvironmentStrings("%APPDATA%")
 
Set objWord = CreateObject("Word.Application")
objWord.Visible = False
 
Set objNormalTemplate = objWord.Documents.Open(appDataPath & "\Microsoft\Templates\Normal.Dotm")
normalTemplateVersion = GetVersionNumber(objNormalTemplate)
objNormalTemplate.Close
 
Set objSetupWordCitrix = objWord.Documents.Open(appDataPath & "\Word\Support\SetupWord.dotm")
setupWordCitrixVersion = GetVersionNumber(objSetupWordCitrix)
If normalTemplateVersion < setupWordCitrixVersion Then
objWord.Run "Main"
End If
objWord.Quit
End If
 
 
Function CDPExists(objDoc, cdpName)
Dim cdp
CDPExists = False
For Each cdp In objDoc.CustomDocumentProperties
If cdp.Name = cdpName Then
CDPExists = True
Exit Function
End If
Next
End Function
 
Function GetVersionNumber(objDoc)
lngVersionNumber = 0
If CDPExists(objDoc, "Version") Then
lngVersionNumber = CLng(objDoc.CustomDocumentProperties("Version").Value)
End If
GetVersionNumber = lngVersionNumber
End Function

 

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

 

The following will check members in a group and make sure they have a custom attritbute value

# Connect to Exchange server and load Exchange powershell modules
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
 
Import-Module ActiveDirectory
 
$groupdn = (Get-ADGroup '#Group Name').DistinguishedName
 
$users = Get-ADUser -Filter {(memberof -eq $groupdn)}
 
foreach($user in $users){
 
#If user is not
if($user.name -ne "Users Name"){
 
#if the CustomAttrribte is Blank
if((Get-Mailbox -Identity $user.name | select -ExpandProperty CustomAttribute1) -eq {}) {
#if the CustomAttrribte is not equal to a value
#if((Get-Mailbox -Identity $user.name | select -ExpandProperty CustomAttribute1) -ne "value") {
#Show their name
 ($user.name) } } }

 

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

PowerShell logo

$users = @("user1","user2")
 
foreach ($user in $users) {
 
$PSEmailServer = "server.domain.local"
 
#Move
New-MoveRequest -identity $user -TargetDatabase "Mailbox Database 1"
 
$MoveStats = Get-MoveRequest -identity $user | Get-MoveRequestStatistics
$MoveStatus = $MoveStats.Status
 
WHILE ($MoveStatus -eq "Queued" -or $MoveStatus -eq "InProgress" -or $MoveStatus -eq "CompletionInProgress") { Start-Sleep 30 
                                     $MoveStats = Get-MoveRequestStatistics -identity $user | Get-MoveRequestStatistics
                                     $MoveStatus = $MoveStats.Status
                                    }
IF ($MoveStatus -eq "Failed") {             
                                  Send-MailMessage -To "email@domain.com" -From "server.domain.local" -Subject "Exchane Mailbox Mover" -Body "The Exchange Mailbox 
 
Export of the $user failed"
                                }
 
IF ($MoveStatus -eq "Completed") { 
#once completed move user from one group to other
import-module activedirectory
$usergroups = (GET-ADUSER –Identity $user –Properties MemberOf).MemberOf
if ($usergroups -match 'Usergroup') { 
Remove-ADGroupMember -Identity "Usergroup" -Members $user -Confirm:$false
Add-ADGroupMember -Identity "NewUserGroup" -Members $user
}
                                   }
 
 }

VN:F [1.9.22_1171]
Rating: 7.5/10 (2 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

PowerShell logoRecently on using a script to create user folders it came up with an error

“Bind” with “2” argument(s): “The specified object was not found in the store.”

I’d seen this before with permissions which I added below:

Add-MailboxPermission -Identity $NewUser -User $currentuser  -AccessRights FullAccess -Automapping $false

However I still got the error. After some investigation as this was a new user , Outlook had never been opened and the Inbox had never been created so it couldn’t create these folders under the inbox. Login to Webmail or Outlook once as the user and it will create!

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

VSTOHow to uninstall vsto

“%CommonProgramFiles%\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe” /uninstall \\path\to\vsto\AddIn.vsto

How to silently install vsto

“%CommonProgramFiles%\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe” /install /silent \\path\to\vsto\AddIn.vsto

How to install via group policy

Bat Login Script

@echo off
REM Check for presence of vsto key first if not found run installer
reg query HKEY_CURRENT_USER\Software\Microsoft\Office\Word\Addins\DCCWord2010 /e >nul 2>nul || ("C:\Program Files\Common Files\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe" /I "\\path\to\vsto\AddIn.vsto" /S)

Turns out using this

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runonce

 

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

vbs file via run registry  ( The advantage of using this is it runs once for each user however they will need to log in twice if they are logged off!)

 

 Turns out using this registy value HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Runonce The user needs to be a local administrator…

So we had to put the value inside here : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run , and let the file remove it after running

Group Policy Registry key to add to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

Link as my hosting doesn’t allow these file types! http://pastebin.com/SNzSP2Xw

vbs script

Dim commandDim WshShellcommand=chr(34) & "%CommonProgramFiles%\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe" & chr(34) & " /Silent /Install " & chr(34) & "\\path\to\vsto\AddIn.vsto" & chr(34)
Set WshShell = WScript.CreateObject("WScript.Shell")WshShell.Run command
'Delete the Run Key to make sure it runs once - we cannot put this in the run one registry due to users not being administrators
Const HKEY_CURRENT_USER = &H80000001
strComputer = "." Set objRegistry=GetObject("winmgmts:\\" & _  strComputer & "\root\default:StdRegProv") strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Run"strValueName = "ExternalPDatabases"
objRegistry.DeleteValue HKEY_CURRENT_USER, strKeyPath, strValueName

 

VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

worksite

Currently you need to purchase imanage mobility server to be able to view NRL files remotely.

We had a request, for users to be able to email Worksite NRL links from any devices especially Mobile devices to an email address and it emails them back the document for review.

It looked like this site software could do it at one stage : http://www.grantselect.co.uk/products/products.htm , however it’s not going anymore , so we developed a Powershell Script to do this.

1) Create a mailbox in Exchange 2010 where you want to get emails sent to . e.g. NRLDocrequest@yourdomain.com.au. Change the value below in the script MAILBOXWHEREREQUESTSGETSENT to the alias of the Email account

2)Under the Inbox create a Folder called Complete and Folder Called External

3)Give the user who will be running this script Send as as well as Full Permissions to mailbox

4)Replace below in script IMANAGESQLSERVERNAME to the SQL server of your iManage Database

5)Where you run this script make sure the user running the script has access to C:\Temp\

6)Add this script as scheduled task to check Mailbox

# Connect to Exchange server and load Exchange powershell modules
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
 
$mailbox = Get-Mailbox MAILBOXWHEREREQUESTSGETSENT
$mailAddress = $mailbox.PrimarySmtpAddress.ToString();
 
[Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll") | Out-Null
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.AutodiscoverUrl($mailAddress);
 
$MailboxRootid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailAddress)
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)
 
# Get Folder ID from Path to be able to move
Function GetFolder()
{
	# Return a reference to a folder specified by path
 
	$RootFolder, $FolderPath = $args[0];
 
	$Folder = $RootFolder;
	if ($FolderPath -ne '\')
	{
		$PathElements = $FolderPath -split '\\';
		For ($i=0; $i -lt $PathElements.Count; $i++)
		{
			if ($PathElements[$i])
			{
				$View = New-Object  Microsoft.Exchange.WebServices.Data.FolderView(2,0);
				$View.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
				$View.PropertySet = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly;
 
				$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $PathElements[$i]);
 
				$FolderResults = $Folder.FindFolders($SearchFilter, $View);
				if ($FolderResults.TotalCount -ne 1)
				{
					# We have either none or more than one folder returned... Either way, we can't continue
					$Folder = $null;
					Write-Host "Failed to find " $PathElements[$i];
					Write-Host "Requested folder path: " $FolderPath;
					break;
				}
 
				$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s, $FolderResults.Folders[0].Id)
			}
		}
	}
 
	$Folder;
}
 
$folderid = new-object  Microsoft.Exchange.WebServices.Data.Folderid([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$mailAddress)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$folderid)
 
$mails = $inboxFolder.FindItems(5) 
$mails | % {$_.Load()}
#foreachemails
foreach($Item in $mails.Items)
	{ 
	#block emails from outside of domain for security
	if($item.Sender.Address -like "*@yourinternaldomain.com") {
 
 
	#only load items with attachments
	if($item.Attachments.Count -gt 0)
		{ 
 
		#Create the email message and set the Subject and Body
		$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $s
 
		#Go through each attachment
		foreach($attach in $item.Attachments)
			{
			#Is it an NRL File?
			if ($attach.name -like '*.nrl') {
 
			#If it it load it to temp location
			$attach.load("C:\Temp\"+$attach.name)
 
			#Start Array for content for NRL
			$var = @{}
			$count=0
 
			#Get NRL file and store to array
			Get-Content -LiteralPath ("C:\Temp\" + $attach.name) | ForEach-Object {
				$count++
				$list = $_.Split(':!')
				$var.Add($count, $list)
				}
 
			#Get Variables from Array
			$database = $var[2][8]
			$docvalue = $var[2][11].Split(',')
			$docnumber = $docvalue[0]
			$docversion = $docvalue[1]
 
			#Remove NRL File
			Remove-Item ("C:\Temp\" + $attach.name)
 
##SQL Query Function no SQL installs needed all powershell baby
function Invoke-SQL ($SQLServer, $SqlQuery)  {
	#Uncomment below to double check the statement
	#Write-Host $SqlQuery
	$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
	$SqlConnection.ConnectionString = "Server = $SQLServer; Integrated Security = True"
 
	$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
	$SqlCmd.CommandText = $SqlQuery
	$SqlCmd.Connection = $SqlConnection
 
	$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
	$SqlAdapter.SelectCommand = $SqlCmd
 
	$DataSet = New-Object System.Data.DataSet
	[void]$SqlAdapter.Fill($DataSet)
 
	$SqlConnection.Close()
	return $dataset.tables
}
 
#Get the Doc Details from Number
$sqlresult = Invoke-SQL IMANAGESQLSERVERNAME "SELECT DOCLOC,DOCNAME,APPEXTENSION FROM [$database].[MHGROUP].DOCMASTER INNER JOIN [$database].[MHGROUP].DOCTYPES ON [$database].[MHGROUP].DOCMASTER.T_ALIAS=[$database].[MHGROUP].DOCTYPES.T_ALIAS where [DOCNUM]='$docnumber' and [VERSION]='$docversion'"
 
#Get the Location of file including imanage file server name
$docloc = $sqlresult| select -expand DOCLOC
$docloc = $docloc.Split(':')
$doclocsrv = $docloc[0]
 
#get the doc name to rename or it will be doc number
$docname = $sqlresult| select -expand DOCNAME
 
#get the doc type
$docfileextension = $sqlresult| select -expand APPEXTENSION
 
#Get the unc path of file to copy
$sqlresult = Invoke-SQL IMANAGESQLSERVERNAME "SELECT LOCATION  FROM [$database].[MHGROUP].DOCSERVERS where [DOCSERVER]='$doclocsrv'"
$location = $sqlresult| select -expand LOCATION
$source = $location + $docloc[1]
$destination = $docname + "." + $docfileextension
$pattern = "[{0}]" -f ([Regex]::Escape( [System.IO.Path]::GetInvalidFileNameChars() -join '' ))
$destination = "C:\Temp\NRL\" + [Regex]::Replace($destination, $pattern, '')
 
copy-item $source -Destination $destination
 
$message.Attachments.AddFileAttachment($destination) | Out-Null
 
#End of NRL Loop
}
#End of For Each Attachment
}
#End of the if attachment exists
}
 
#Is the email being sent have any documents to send?
if ($message.Attachments.Count -gt 0){
 
	$message.From = “email@fromdomain.com.au”
	$message.Subject = $item.Subject
	$message.Body = $msgBody
 
	$message.ToRecipients.Add($item.Sender.Address)
 
	#Send the message and save a copy in the users Sent Items folder (Alt is message.Send which will not save a copy.)
	if($item.Sender.Address -ne "emails@toignore.com")
		{
		$message.SendAndSaveCopy()
		}
 
}
 
 
#Move to Folder After Replying
$FolderObject = GetFolder($MailboxRoot, "\Inbox\Complete\");
		try
		{
		$Item.Move($FolderObject.Id) | out-null;
		}
		catch
		{
		Write-Host "Failed to move item", $Item.Id.UniqueId
		}
 
Remove-Item c:\TEMP\NRL\*
 
#Loop per email
 
}
 
#Move to Folder After Replying
$FolderObject = GetFolder($MailboxRoot, "\Inbox\External\");
		try
		{
		$Item.Move($FolderObject.Id) | out-null;
		}
		catch
		{
		Write-Host "Failed to move item", $Item.Id.UniqueId
		}
 
}

 

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

140257-thumb_exchange_original[1]

# set Identity to distributiongroup alias
$distributiongroup = Get-DistributionGroup -Identity "#Distribution Group Name"
 
$groupmembers = Get-DistributionGroupMember -Identity $distributiongroup | Where-Object { $_.RecipientType -eq "UserMailbox" }
 
foreach ( $member in $groupmembers )
{
$intRec = 0
#Gets the SMTP Address of Mailbox
$smtp = Get-Mailbox -Identity $member.alias | Select -Property PrimarySmtpAddress
#Change Start and End Date where needed, Change source to STOREDRIV for Internal or remove where for all messages ( SMTP = External )
Get-TransportServer | Get-MessageTrackingLog -ResultSize Unlimited -Start “02/01/2015” -End “02/28/2015” -Recipients $smtp.PrimarySmtpAddress -EventID RECEIVE | where {$_.source -eq 'SMTP'} | 
 
ForEach { $intRec++ }
Write-Host "E-mails received from External Source by"$smtp.PrimarySmtpAddress "-" $intRec
 
}

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

powershell2xa4

Param(
[string]$foo,
)

./Powershellscript.ps1 -foo "Bar1 bar2/ Bar3/Bar4"

When I ran the above as a scheduled task the output I would get for $foo is Bar1 bar2/ Bar3

When I ran the below as a scheduled task ( Single Quotes ) the output I would get for $foo is Bar1 bar2/ Bar3/Bar4 (Correct )

./Powershellscript.ps1 -foo 'Bar1 bar2/ Bar3/Bar4'

So why?

When you run powershell.exe from inside Powershell you are forcing the arguments to go through the old Windows style command line processing.

This way all of the arguments will pass right through without being converted to strings, having double quotes stripped and then being re-parsed.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)