Posts Tagged ‘powershell’

Per my backup script before , this restores

You will need to go through and change the values in %

 

$mailbox = Get-Mailbox %mailbox%
$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]::Exchange2010_SP1)
$s.AutodiscoverUrl($mailAddress);
 
 
$cred = New-Object System.Net.NetworkCredential("%username%","%password%")
 
 
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$s.Credentials = $cred
 
$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;
}
 
 
$file = [System.IO.File]::ReadAllBytes("c:\%folder%\%binaryfile%")
$data = [System.Convert]::ToBase64String($file)
 
#change folder where needed
$folderobject = GetFolder($MailboxRoot, "\Quick Step Settings\");
$folderid = $folderobject.id.uniqueid
$folderchangekey = $folderobject.id.ChangeKey
 
$expRequest = @"
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
      xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2010_SP1" />
  </soap:Header>
  <soap:Body>
  <m:UploadItems>
      <m:Items>
        <t:Item CreateAction="CreateNew" IsAssociated="true">
          <t:ParentFolderId  Id="$folderid" ChangeKey="$folderchangekey"/>
          <t:Data>$data</t:Data>
        </t:Item>
      </m:Items>
    </m:UploadItems>
  </soap:Body>
</soap:Envelope>
"@
 
$mbMailboxFolderURI = New-Object System.Uri($s.url)
$wrWebRequest = [System.Net.WebRequest]::Create($mbMailboxFolderURI)
$wrWebRequest.KeepAlive = $false;
$wrWebRequest.Headers.Set("Pragma", "no-cache");
$wrWebRequest.Headers.Set("Translate", "f");
$wrWebRequest.Headers.Set("Depth", "0");
$wrWebRequest.ContentType = "text/xml";
$wrWebRequest.ContentLength = $expRequest.Length;
$wrWebRequest.Timeout = 60000;
$wrWebRequest.Method = "POST";
$wrWebRequest.Credentials = $cred
$bqByteQuery = [System.Text.Encoding]::ASCII.GetBytes($expRequest);
$wrWebRequest.ContentLength = $bqByteQuery.Length;
$rsRequestStream = $wrWebRequest.GetRequestStream();
$rsRequestStream.Write($bqByteQuery, 0, $bqByteQuery.Length);
$rsRequestStream.Close();
$wrWebResponse = $wrWebRequest.GetResponse();
$rsResponseStream = $wrWebResponse.GetResponseStream()
$sr = new-object System.IO.StreamReader($rsResponseStream);
$rdResponseDocument = New-Object System.Xml.XmlDocument
$rdResponseDocument.LoadXml($sr.ReadToEnd());
$Datanodes = @($rdResponseDocument.getElementsByTagName("m:ResponseCode"))
$Datanodes
GD Star Rating
loading...
GD Star Rating
loading...

Wow , possible my biggest EWS Powershell script, Big thanks go to Glen for the missing piece of the jigsaw. The project started as a way to copy Quick Copy settings between users when needed.

Outlook doesn’t provide much functionality to do this itself, you can use the famous redemtion.dll for this task  http://www.dimastr.com/redemption/rdoquicksteps.htm , but I’m more of a server side guy than a client side, Our Outlook Enviroment has too many macros already!

I knew how to get more Inbox items , but have never dived into the “Associated Contents Table”. Using the free MFCMAPI.exe tool , I explored the mailbox to find the folder I need as well as the table and after hours or tinkering and borrowing code we are good!

You will need to go through and change the values in %

This is the download script , I will paste the SOAP upload script in another post

$mailbox = Get-Mailbox %mailbox%
$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]::Exchange2010_SP1)
$s.AutodiscoverUrl($mailAddress);
 
#needed for XML Soap
$cred = New-Object System.Net.NetworkCredential("%username%","%password%")
 
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$s.Credentials = $cred
 
$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;
}
#choose the folder name you want to download the Configuration items from
$folderobject = GetFolder($MailboxRoot, "\Quick Step Settings\");
$sfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM.Microsoft.CustomAction")
$Itemview = new-object Microsoft.Exchange.WebServices.Data.ItemView(20)
$ItemView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$ItemView.Traversal = [Microsoft.Exchange.Webservices.Data.ItemTraversal]::Associated
#$folderid = new-object  Microsoft.Exchange.WebServices.Data.Folderid([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$mailAddress)
$folderid = $folderobject.Id
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$folderid)
$pspropset = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)
$mails  = $inboxFolder.finditems($sfSearchFilter,$Itemview)
 
#loop to go through all the items in the folder
$count=0
foreach($Item in $mails.Items)
{ 
 
#gets the id for the SOAP XML Request
$itemid = $mails.Items[$count].Id.Uniqueid
 
$expRequest = @"
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
      xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2010_SP1" />
  </soap:Header>
  <soap:Body>
    <m:ExportItems>
      <m:ItemIds>
        <t:ItemId Id="$itemid"/>
      </m:ItemIds>
    </m:ExportItems>
  </soap:Body>
</soap:Envelope>
"@
$mbMailboxFolderURI = New-Object System.Uri($s.url)
$wrWebRequest = [System.Net.WebRequest]::Create($mbMailboxFolderURI)
$wrWebRequest.KeepAlive = $false;
$wrWebRequest.Headers.Set("Pragma", "no-cache");
$wrWebRequest.Headers.Set("Translate", "f");
$wrWebRequest.Headers.Set("Depth", "0");
$wrWebRequest.ContentType = "text/xml";
$wrWebRequest.ContentLength = $expRequest.Length;
$wrWebRequest.Timeout = 60000;
$wrWebRequest.Method = "POST";
$wrWebRequest.Credentials = $cred
$bqByteQuery = [System.Text.Encoding]::ASCII.GetBytes($expRequest);
$wrWebRequest.ContentLength = $bqByteQuery.Length;
$rsRequestStream = $wrWebRequest.GetRequestStream();
$rsRequestStream.Write($bqByteQuery, 0, $bqByteQuery.Length);
$rsRequestStream.Close();
$wrWebResponse = $wrWebRequest.GetResponse();
$rsResponseStream = $wrWebResponse.GetResponseStream()
$sr = new-object System.IO.StreamReader($rsResponseStream);
$rdResponseDocument = New-Object System.Xml.XmlDocument
$rdResponseDocument.LoadXml($sr.ReadToEnd());
$Datanodes = @($rdResponseDocument.getElementsByTagName("m:Data"))
$Datanodes
if ($Datanodes.length -ne 0){
	$Data = [System.Convert]::FromBase64String($Datanodes[0].'#text')
#file location
	$fsFileStream = new-object system.io.filestream C:\%folder%\quickcopy$count, ([io.filemode]::create), ([io.fileaccess]::write), ([io.fileshare]::none)
	$fsFileStream.Write($Data, 0, $Data.Length);
    $fsFileStream.Close();
}
$count= $count+1 
 
	}

 

GD Star Rating
loading...
GD Star Rating
loading...

PowerShell logoRecently we need to search a load of servers locally for files that existed ( lingered ) on peoples local user proflile

Get-ChildItem -Recurse -Force \\servername\c$\Users\*\AppData\Local\Temp | Where-Object {$_.Name -like "[email protected]*.tmp"} | Export-CSV C:\TempFiles.csv -Append

We then needed to search roaming directories mapped on a file server , I tried to use the above for this command replacing the directory location with a roaming file server location replace * with Users again, however I was getting “Get-ChildItem : Access is denied” with UnauthorizedAccessException , probably because query is too generic! To limit this down, I used the following pipe to query the list of users and then check each folder after

Get-ChildItem "\\domain.local\dfs\location\*" | ForEach-Object {
 
Get-ChildItem -Recurse -Force $_"\AppData\Roaming\Software"   | Where-Object {$_.Name -like "[email protected]*.tmp"}} | Export-CSV C:\Files.csv -Append

 

GD Star Rating
loading...
GD Star Rating
loading...

 

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) } } }

 

GD Star Rating
loading...
GD Star Rating
loading...

This Exports a report of emails and also a copy of all the emails to a mailbox ( Disovery ) you can do this via the Web Based Gui : https://youwebmaildomain/ecp/?rfr=owa with the right user permissions

New-MailboxSearch -Name "WeekendOutage-Search" -StartDate "1/1/2009" -EndDate "12/31/2009" -SourceMailboxes "Amit Tank" -TargetMailbox "Discovery Search Mailbox" -SearchQuery '"Weekend" and "Outage"' -MessageTypes Email -IncludeUnsearchableItems -LogLevel Full

But you cannot exclude emails from specific domains from this discovery search .e.g only sent from Externally. You can exclude Generic Keywords using NOT in the -SearchQuery but its generic to the email like the search Query above.

The New-MailboxExportRequest Should be able to do this but it doesn’t , just exports everything probably because the operator is too specific and doesn’t suport -notlike 🙁

New-MailboxExportRequest -Mailbox "Discovery Search Mailbox" -contentfiler{sender -ne "*@internaldomain.com"} -Filepath \\samba\share\withexchangepermissions\file.pst

But we can actually just delete all the Internal Mail using Search Mailbox

 

Search-Mailbox -Identity "Discovery Search Mailbox" -searchquery 'From:"@internaldomain.com"' -DeleteContent

Now we can just export this to a PST

New-MailboxExportRequest -Mailbox "Discovery Search Mailbox" -Filepath \\samba\share\withexchangepermissions\file.pst
GD Star Rating
loading...
GD Star Rating
loading...

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
}
                                   }
 
 }

GD Star Rating
loading...
GD Star Rating
loading...

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
		}
 
}

 

GD Star Rating
loading...
GD Star Rating
loading...

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.

GD Star Rating
loading...
GD Star Rating
loading...

Powershell script to query multiple servers for their Local Machine Run Registry Keys

$servers = Get-Content c:\scripts\servers.txt 
 foreach ($server in $servers) {
 
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $server.ServerName)
$RegKey= $Reg.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run")
 
$server
$RegKeyRO.GetValueNames()
}

 

GD Star Rating
loading...
GD Star Rating
loading...

Below is the command to extract ( Archive ) emails from a particular folder into a PST

#Archive Items from a certain folder
New-MailboxExportRequest -mailbox %mailboxname% -IncludeFolders "path/to/folder/ -ContentFilter {(Received -lt '08/01/2014')} -FilePath \\path\to\pstfile.pst

However due to Exchange updates , the MailboxExport command does not work anymore ( which had the -deletecontent command) and Search-Mailbox does not have any functionality to Include just specific folders. So we have to use powershell EWS below

Note – By default ItemView has a limit of 1000 in exchange, the command below you will probably want to increase this say to 10,000 or even 50,000 so you don’t have to rerun this lots of times. After each run it will tell you how many items it has deleleted. You need to run the powershell script with a useraccount that has a throttling policy set above 1000.

e.g. Set-ThrottlingPolicy PolicyName -EWSFindCountLimit 50000

Set-Mailbox useraccount -ThrottlingPolicy PolicyName

$mailbox = Get-Mailbox %mailboxname%
$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]::Exchange2010)
$s.AutodiscoverUrl($mailAddress);
 
$ItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(10000)
$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;
}
 
 
try {
 
	$FolderObject = GetFolder($MailboxRoot, "path\folder\");
#Date from and To
    $findItemResults = $FolderObject.FindItems("System.Message.DateReceived:01/01/2014..01/08/2014",$ItemView)
 
        foreach ($item in $findItemResults.Items) {
 
                try {
#Comment Below out to not delete
                    [void]$item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
                    $Deleted ++
#Uncomment below to list before deleting
					#Write-host $item.DateTimeReceived 
                } catch {
                    Write-warning "Unable to delete item, $($item.subject).  $($Error[0].Exception.Message)"
                }
            }        
 
 
    if ($Deleted -gt 0) { Write-host "$Deleted mail items deleted from the Inbox." }
} catch {
    Write-warning "Could not connect to Inbox.  $( $_.exception.message )"
}
GD Star Rating
loading...
GD Star Rating
loading...