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)

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

 

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

Rebuilding profiles can sometimes be time consuming especially documenting settings. I created a script to backup the current printers the User had and wrote it to a test file ( including Default Printer ) so that this could be run to backup , then restored from this file in the Restore Script

Backup Printer List

Const ForWriting = 2
 
Set objNetwork = CreateObject("Wscript.Network")
 
strComputer = "."
 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
 
Set DefPrinters = objWMIService.ExecQuery _
     ("Select * from Win32_Printer Where Local = FALSE AND Default = True")
 
For Each DefPrinter in DefPrinters
    strText = strText & "Default : " & DefPrinter.Name & vbCrLf
Next
 
Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where Local = FALSE AND Default = False")
 
For Each objPrinter in colPrinters
    strText = strText & objPrinter.Name & vbCrLf
Next
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
Set objFile = objFSO.CreateTextFile _
    ("h:\Printers.txt", ForWriting, True)
 
 
objFile.Write strText
 
objFile.Close

 

Restore Printer List

 

Const ForReading = 1
Const TristateUseDefault=-2
Set wshnet = CreateObject("Wscript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile ("h:\Printers.txt", ForReading, True, TristateUseDefault)
 
Do Until objFile.AtEndOfStream
	strNextLine = objFile.Readline
	if left(strNextLine,10) = "Default : " THEN
		strNextLine = replace(strNextLine, "Default : ", "")	
		wshnet.AddWindowsPrinterConnection strNextLine
		wshnet.SetDefaultPrinter strNextLine
	END IF
	wshnet.AddWindowsPrinterConnection strNextLine
Loop
 
objFile.Close

 

 

How to reset Printers after backup then restore

 

Const ForWriting = 2
 
Set objNetwork = CreateObject("Wscript.Network")
 
strComputer = "."
 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
 
Set DefPrinters = objWMIService.ExecQuery _
     ("Select * from Win32_Printer Where Local = FALSE AND Default = True")
 
For Each DefPrinter in DefPrinters
    strText = strText & "Default : " & DefPrinter.Name & vbCrLf
Next
 
Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where Local = FALSE AND Default = False")
 
For Each objPrinter in colPrinters
    strText = strText & objPrinter.Name & vbCrLf
Next
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
strDirectory = objFSO.BuildPath(WshShell.SpecialFolders("Desktop"), "Printers.txt")
 
Set objFile = objFSO.CreateTextFile _
    (strDirectory, ForWriting, True)
 
 
objFile.Write strText
 
objFile.Close
 
 
Const HKEY_CLASSES_ROOT  = &H80000000
Const HKEY_CURRENT_USER  = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS         = &H80000003
 
' Object used to get StdRegProv Namespace
Set wmiLocator = CreateObject("WbemScripting.SWbemLocator")
 
' Object used to determine local machine name
Set wshNetwork = CreateObject("WScript.Network")
 
' Registry Provider (StdRegProv) lives in root\default namespace.
Set wmiNameSpace = wmiLocator.ConnectServer(wshNetwork.ComputerName, "root\default")
Set objRegistry = wmiNameSpace.Get("StdRegProv")
 
' Deletes Key with alle subkeys
sPath = "Printers"
 
lRC = DeleteRegEntry(HKEY_CURRENT_USER, sPath)
 
Function DeleteRegEntry(sHive, sEnumPath)
' Attempt to delete key.  If it fails, start the subkey
' enumration process.
lRC = objRegistry.DeleteKey(sHive, sEnumPath)
 
' The deletion failed, start deleting subkeys.
If (lRC <> 0) Then
 
' Subkey Enumerator
   On Error Resume Next
 
   lRC = objRegistry.EnumKey(HKEY_CURRENT_USER, sEnumPath, sNames)
 
   For Each sKeyName In sNames
      If Err.Number <> 0 Then Exit For
      lRC = DeleteRegEntry(sHive, sEnumPath & "\" & sKeyName)
   Next
 
   On Error Goto 0
 
' At this point we should have looped through all subkeys, trying
' to delete the registry key again.
   lRC = objRegistry.DeleteKey(sHive, sEnumPath)
 
End If
 
End Function
 
Const ForReading = 1
Const TristateUseDefault=-2
Set wshnet = CreateObject("Wscript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
strDirectory = objFSO.BuildPath(WshShell.SpecialFolders("Desktop"), "Printers.txt")
 
Set objFile = objFSO.OpenTextFile (strDirectory, ForReading, True, TristateUseDefault)
 
Do Until objFile.AtEndOfStream
              strNextLine = objFile.Readline
              if left(strNextLine,10) = "Default : " THEN
                             strNextLine = replace(strNextLine, "Default : ", "")            
                             wshnet.AddWindowsPrinterConnection strNextLine
                             wshnet.SetDefaultPrinter strNextLine
              END IF
              wshnet.AddWindowsPrinterConnection strNextLine
Loop
 
objFile.Close
 
x=msgbox("Printer ReMap Complete" ,0, "Tech Services")

 

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