Jump to content
Sign in to follow this  
kor

Working with Powershell and Exchange

Recommended Posts

kor

My working code

Func _CreateMailbox()
    _Message("10 : Creating Exchange mailbox")
    If $sHailFrom = "createstudent" Or $sHailFrom = "bulkcreatestudent" Then
        ; Logic to determine exchange database placement
        If StringRegExp($sLastName, "(?i)^[a-l]") = 1 Then
            $sExchangeDB = "Students-A-L"
        ElseIf StringRegExp($sLastName, "(?i)^[m-z]") = 1 Then
            $sExchangeDB = "Students-M-Z"
        Else
            _Message("10 : ERROR : " & $aErrors[3]) ; unknown location
        EndIf
    EndIf
    ; First check if exchange mailbox exists
    $sCheckMailbox = "get-user -Identity " & $sUsername & " |select RecipientType"
    ClipPut("")
    RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe -ImportSystemModules -command " & $sCheckMailbox & " | ft -hide | clip", "C:", @SW_HIDE)
    $sPowershell = ClipGet()
    $sSearch = StringInStr($sPowershell, "Mailbox")
    If $sSearch = 0 Then
        ; Create the mailbox
        $createmailbox = "Enable-Mailbox -Identity " & $sUsername & "@ad.domain.org -Alias """ & $sUsername & """ -Database """ & $sExchangeDB & """" ; do not modify this command
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe -ImportSystemModules -command " & $createmailbox, "C:", @SW_HIDE)
        Sleep(2000)
        ; Check to make sure mailbox was created
        ClipPut("")
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe -ImportSystemModules -command " & $sCheckMailbox & " | ft -hide | clip", "C:", @SW_HIDE)
        $sPowershell = ClipGet()
        $iDidCreate = StringInStr($sPowershell, "Mailbox")
        If $iDidCreate = 0 Then _Message("10.1 : ERROR : " & $aErrors[11]) ; error creating mailbox
    Else
        ; mailbox already exists
        _Message("10.1 : ERROR : " & $aErrors[8]) ; duplicate mailbox
    EndIf
    If $sHailFrom = "createstudent" Or $sHailFrom = "bulkcreatestudent" Then
        ; HideFromAddressBook
        _Message("10 : Hiding from address book")
        $sHideFromAddressLists = "Get-Mailbox -Identity " & $sUsername & " | Set-Mailbox -HiddenFromAddressListsEnabled $true"
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe -ImportSystemModules -command " & $sHideFromAddressLists, "C:", @SW_HIDE)
        ; /HideFromAddressBook
    EndIf
    Sleep(100)
    _Message("10 : Creating Exchange mailbox.....Done")
    Sleep(2000)
EndFunc   ;==>_CreateMailbox

I'm wondering if any guru's can help me make this code more efficient when working with powershell. Currently when importing the exchange modules it takes my powershell window about 10 seconds to import all the modules correctly before I can start issuing commands.

I'm wondering if there is easier ways to create and modify exchange mailboxes in autoit. Maybe a UDF to work with powershell easier that I am not aware of.

Edited by kor

Share this post


Link to post
Share on other sites
JLogan3o13

Hi, kor. Have you looked through Water's excellent I honestly don't know how well it integrates with what you're trying to do in Exchange, but it is a good place to start.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
kor

I guess no one here likes working with powershell.

It's necessary though because I have to create exchange mailboxes inside autoit.

I have identified that I don't necessarily need to run the full -ImportSystemModules command for powershell, I can get away with running "Add-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010" however it seems you can't pass a snapin module when opening the powershell.exe. The best I have been able to do is add the pssnapin command as a PS1 file then have autoit run the following.

""PowerShell.exe -noexit C:exchange.ps1""

My main issue is that while this opens a powershell window, I don't know how to continue to run commands against this window in autoit. How do I open a command/powershell window then continue to issue commands to that same window?

Share this post


Link to post
Share on other sites
kor

Finally figured it out. You can do it a few ways.

Powershell.exe -noexit C:Exchange.ps1; <command2>

(adding a semicolon after each command allows running multiple cmdlets on a single line)

OR

PowerShell.exe -PSConsoleFile "C:Program FilesMicrosoftExchangeServerV14BinExShell.Psc1" -Command "<command2>"

Source : http://social.technet.microsoft.com/Foru...ad/14b4df48-f6c7-4b71-b296-40b

Now I don't need to try and work with the window handle, I can just issue the commands I need.

Edited by kor

Share this post


Link to post
Share on other sites
water

My OutlookEX doesn't help with creating a mailbox on an Exchange server. You need the Active Directory UDF, function _AD_CreateMailbox. This function uses CDO and therefore isn't any longer supported my MS starting with Exchange 2010.

You have to use PowerShell. I got it working, but it takes forever.

Our user provisioning script creates a user account in AD, creates some directories and sets permissions on them, creates a mailbox.

If you like I can post the code I use (as soon as I'm in my office again).


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
brockjd

I'd definitely be interested in your provisioning script as we just moved to Exchange 2010 and am looking for ways to consolidate our AD/mailbox creation.

Share this post


Link to post
Share on other sites
water

Our provisioning script is started by our ServiceDesk software.

Our HR department enters all data of new employees 14 days before he/she actually starts to work.

The ServiceDesk software imports all employee records from SAP HR and starts the provisioning script for every new employee.

The AutoIt scripts creates the user account, adds the user to some AD groups, creates some directories on our fileservers (home, profile, mailarchive directory), sets the permissions on this directories using XCACLS and creates a mailbox on our Exchange 2010 server for this user.

All actions and the results are logged.

When the script runs successfully a mail is sent to the ServiceDesk software which then creates a change record, immediately closes it and sends a close message to the IT contact in the corresponding department. The IT contact can then order hard- and software for the new employee so when the new employee starts working all IT equipment is already set up.

If an error occurres (user account already defined or whatever) a mail is sent to the ServiceDesk software to create an incident.

That's how we do it in short :oops:


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

This is the code snippet where I create the Exchange Maibox:

;------------------------------------------------------------------------------------------
; In some cases the mail address is not created by Exchange but by this script.
; Parameter -PrimarySmtpAddress has to be passed to the PowerSheell script.
;------------------------------------------------------------------------------------------
$asVorname = StringSplit($Vorname, "/")
If @error = 0 Then ; Separator found
    $sSMTPAddress = " -PrimarySmtpAddress " & $asVorname[1] & "." & $Nachname & $asVorname[2] & "@" & $sMaildomain
    _FileWriteLog($sLogFile, "I " & $Kurzzeichen & ": Parameter PrimarySmtpAddress auf '" & $sSMTPAddress & "' gesetzt")
Endif
$sCMD = "C:\Windows\System32\WindowsPowerShellv1.0powershell.exe -command . " & _
"'D:Exchange ServerV14binRemoteExchange.ps1'; Connect-ExchangeServer -auto; Enable-Mailbox -Identity " & _
$Kurzzeichen & " -Alias " & $Kurzzeichen & " -Database " & $sEXDatabase & $sSMTPAddress
$PID = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
StdinWrite($PID, @CRLF)
StdinWrite($PID)
; Ausgabe von STDOUT
$sSTDOUT = ""
While 1
    $sOutput = StdoutRead($pid)
    If @error Then ExitLoop
If $sOutput <> "" Then $sSTDOUT = $sSTDOUT & @CRLF & $sOutput
WEnd
; Ausgabe von STDERR
$sSTDERR = ""
While 1
    $sOutput = StdErrRead($pid)
    If @error Then ExitLoop
If $sOutput <> "" Then $sSTDERR = $sSTDERR & @CRLF & $sOutput
WEnd
If StringStripWS($sSTDERR, 3) = "" Then
_FileWriteLog($sLogFile, "I " & $Kurzzeichen & ": Mailbox in Database '" & $sEXDatabase & "' erfolgreich angelegt.")
Else
Exit _Error("E " & $Kurzzeichen & ": Fehler bei der Einrichtung der Exchange Mailbox in Database '" & $sEXDatabase & "'!" & @CRLF & $sSTDERR)
Endif

Variable names and comments are in german but if you have any questions just post here and I will answer your questions.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
kor

@water, here is my updated code. It is much faster than my old method of running the full -ImportSystemModules

; create mailbox
    Local $sExShell = "-PSConsoleFile ""C:Program FilesMicrosoftExchange ServerV14BinExShell.Psc1"""
    Local $sCheckMailbox = "get-user -Identity " & $sUsername & " |select RecipientType"
    ClipPut("") ; clear clipboard
    _Message("Creating exchange mailbox")
    RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe " & $sExShell & " -Command " & $sCheckMailbox & " | ft -hide | clip", "C:", @SW_HIDE) ; does mailbox exist
    If StringInStr(ClipGet(), "Mailbox") = 0 Then ; if mailbox not found
        _Message()
        Local $sCreateMailbox = "Enable-Mailbox -Identity " & $sUsername & "@" & $sDomain & " -Alias """ & $sUsername & """ -Database """ & $sExchangeDB & """"
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe " & $sExShell & " -Command " & $sCreateMailbox, "C:", @SW_HIDE) ; create mailbox
        Sleep(2000)
        ClipPut("") ; clear clipboard
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe " & $sExShell & " -Command " & $sCheckMailbox & " | ft -hide | clip", "C:", @SW_HIDE) ; does mailbox exist
        If StringInStr(ClipGet(), "Mailbox") = 0 Then _Message("ERROR - Error creating mailbox", True)
    Else
        _Message("ERROR - Mailbox already exists", True)
    EndIf
    If $sHail = "StudentAdd" Then
        $sHideMailbox = "Get-Mailbox -Identity " & $sUsername & " | Set-Mailbox -HiddenFromAddressListsEnabled $true"
        _Message("Hiding mailbox from address book")
        RunAsWait($sAdminUser, $sDomain, $sAdminPass, 0, "PowerShell.exe " & $sExShell & " -Command " & $sHideMailbox, "C:", @SW_HIDE)
    EndIf
    ; /create mailbox

Share this post


Link to post
Share on other sites
l4tran

I'm curious.

I hardly ever use Powershell, only during Installs or Setup phase. Does the script above have to be running on the Exchange server? Can you initiate the script on another computer? Like Water's AD.auf UDF as long as you have admin privilages?

Share this post


Link to post
Share on other sites
water

The script I posted above can be run from any computer as long as the Exchange extensions are installed on the machine and you run the script in 64 bit mode.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
l4tran

How do you get it to work without passing -Password in Powershell? My script failed because Powershell is waiting for a password prompt.

Share this post


Link to post
Share on other sites
water

The code I have posted in #8 doesn't need a password to create a mailbox.

How does your PowerShell script look like?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
l4tran

powershell.exe  -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\Bin\ExShell.Psc1" -Command New-Mailbox -Name "Test" -UserPrincipalName "Test@abc.com" -Database "ABC Storage Group\ABC Mailbox Database" -OrganizationalUnit "ou=ABC,ou=Email Hosting,dc=ABC,dc=Com" -Alias "Test" -DisplayName "ABC's Test" -Firstname "ABC" -Lastname "Test"
If I paste the whole script in Command Prompt, Powershell doesn't understand my Database.If I paste from New-Mailbox to the end in Exchange Powershell, the script works but prompts for Password.

Edited by l4tran

Share this post


Link to post
Share on other sites
l4tran

$user = StringLeft($accounts[2], StringInStr($accounts[2], '@') - 1)
$sCreateMailbox = 'powershell.exe -PSConsoleFile "C:Program FilesMicrosoftExchange ServerBinExShell.Psc1" -command . ' & _
'New-Mailbox -name "' & $user & _
'" -UserPrincipalName "' & $accounts[2] & _
'" -Database "' & $sEXDatabase[$index] & ' Storage Group' & '' & $sEXDatabase[$index] & ' Mailbox Database' & _
'" -OrganizationalUnit "' & $emailOU[$index] & ',dc=ABC,dc=COM' & _
'" -Alias "' & $user & _
'" -DisplayName "' & $displayname[$index] & ' ' & $user & _
'" -Firstname "' & $displayname[$index] & _
'" -Lastname "' & $user & '"'


;MsgBox(0,"",$sCreateMailbox)
ClipPut($sCreateMailbox)
RunWait($sCreateMailbox);,@SW_HIDE)

Share this post


Link to post
Share on other sites
water

I can only provide the code I posted in #8. The Powershell code was given to me by our Exchange admin.

Creation of the user is made by my AD UDF. The creation of the mailbox is then made by calling Powershell.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
l4tran
It's prompting for a password. I'm not using RemoteExchange.ps1 since I don't have it in my system, so I the only thing that is close is Exchange.ps1. Could this be the problem?

Share this post


Link to post
Share on other sites
water

You need to install Exchange Management Tools on the system where you want to run the AutoIt script. RemoteExchange.ps1 is installed with the tools.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
l4tran

I've just noticed you and kor have enable-mailbox -Identity in your powershell script. This by definition, creates a mailbox in Exchange for an existing user in Active Directory. If the user already existed, no password needs to be set. Your script doesn't create a user in AD, it creates a mailbox for the existing user in AD.

Share this post


Link to post
Share on other sites
water

Correct. That's what I have described in post #8 and #16.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×