54

Here is my current code:

Write-output “ENTER THE FOLLOWING DETAILS - When Creating Multiple New Accounts Go to           EMC hit F5(refresh) and make sure previous new account is listed before proceeding to the       next one”
$DName = Read-Host “User Diplay Name(New User)"
$RUser = Read-Host "Replicate User(Database Grab)"
$RData = ((Get-Mailbox -Identity $RUser).Database).DistinguishedName
$REmailInput = Read-Host “Requester's Name(Notification Email goes to this Person)"
$REmail = ((Get-Mailbox -Identity "$REmailInput").PrimarySmtpAddress).ToString()

Enable-Mailbox -Identity "$DName" -Database "$RData" 
Set-CASMailbox -Identity "$DName" -ActiveSyncEnabled $false -ImapEnabled $false -    PopEnabled $false


Send-MailMessage -From "John Doe <John.Doe@xyz.com>" -To $REmail -Subject       "$DName's email account" -Body "$DName's email account has been setup.`n`n`nJohn Doe`nXYZ`nSystems Administrator`nOffice: 123.456.7890`nJohn.Doe@xyz.com" -SmtpServer exchange@xyz.com

This code works flawlessly about half the time, but the other half I get this error in return:

ENTER THE FOLLOWING DETAILS - When Creating Multiple New Accounts Go to EMC hit
F5(refresh) and make sure previous new account is listed before proceeding to
the next one
User Diplay Name(New User): Jane Doe
Replicate User(Database Grab): Julie Doe
Requester's Name(Notification Email goes to this Person): Joanna Doe

Name                      Alias                ServerName       ProhibitSendQuo
                                                            ta
----                      -----                ----------       ---------------
Jane Doe                  JDDAFA               exchange@xyz.com      unlimited
Set-CASMailbox : Jane Doe is not a mailbox user.
At C:\emailclientbasic.ps1:11 char:15
+ Set-CASMailbox <<<<  -Identity "$DName" -ActiveSyncEnabled $false -ImapEnable
d $false -PopEnabled $false
+ CategoryInfo          : NotSpecified: (0:Int32) [Set-CASMailbox], Manage
mentObjectNotFoundException
+ FullyQualifiedErrorId : 292DF1AC,Microsoft.Exchange.Management.Recipient
Tasks.SetCASMailbox

So if anyone could help me throw in some kind of wait command after the mailbox is created and wait until the user's mailbox is created before the script disables ActiveSync, etc it would be really helpful. I believe that simply using the -wait switch does not work.

Paul Masek
  • 722
  • 2
  • 7
  • 16

5 Answers5

119

Use the Start-Sleep command:

Start-Sleep -s 10

will pause the script for 10 seconds.

Sven
  • 97,248
  • 13
  • 177
  • 225
  • Thanks Sven! I very well might use this, but I would like something more efficient especially for when I'm adding multiple accounts. Also, the nature of this problem in the first place is that there are varying amounts of time each time Exchange mail enables accounts, hence the fact that it does work fine half of the time. – Paul Masek May 17 '11 at 14:48
  • 5
    I don't use Exchange, so I am not familiar with cmdlets regarding this, but what I would do is trying to find a command that checks if the resource exists and if not, goes into a holding cycle until it exists. Something like this: `while ( res-not-exist ) { Start-Sleep -s 1}` This way, you stop the script only as long as it necessary and only if it is necessary. – Sven May 17 '11 at 15:00
  • Wow! Yeah I agree that sounds like a great way to go! Can anyone else add to Sven's idea? Is this a feasible way to go? – Paul Masek May 17 '11 at 15:13
  • I am temporarily using your initial suggestion for now... +1 I did change it to 5 seconds and that seems to be sufficient. – Paul Masek May 23 '11 at 18:46
8

I had to deal with some timing in an Exchange script I wrote a while ago. Specifically, I needed to modify permissions on a newly created distribution group, but needed to wait until the distribution-group was actually created before attempting to modify it.

do {
    sleep -seconds 1
    $mailboxExists = get-mailboxpermission -Identity "CN=$displayName,$DN" -User "NT AUTHORITY\SELF" -ErrorAction SilentlyContinue |fw IsValid
    write-host "." -nonewline
} while (!$mailboxExists)

It just attempts to get the "IsValid" attribute off of the mailbox (in this example) as a proxy for "mailbox exists". Once get-mailboxpermission returns true, the next step, setting a permission will actually function. The write-host is just to provide a progress bar.

sysadmin1138
  • 131,083
  • 18
  • 173
  • 296
  • hmm, wow, thanks sysadmin1138! It looks like your situation parallels mine exactly so it should theoretically work w/o a hitch. I will try this as well! – Paul Masek May 17 '11 at 17:57
  • @Paul I started out with static waits, but the actual wait needed depended on how loaded the Exchange system was with other things. So I had to go dynamic with it, which works much better! – sysadmin1138 May 17 '11 at 18:19
  • I fully agree, as you would see from my initial responses to @Bret Fisher and @SvenW , that is my same situation exactly. – Paul Masek May 17 '11 at 18:35
  • I'm am trying this now, is the beginning supposed to be a variable or should it not have the $ on the beginning and be a command? It's not working as is. As of right now I have your code inserted right before my "Enable-Mailbox -Identity "$DName" -Database "$RData" line. – Paul Masek May 23 '11 at 18:20
  • I also tried it right after "Enable-Mailbox..." and got this same error, "The term 'false' is not recognized as the name of a cmdlet, function, script fi le, or operable program. Check the spelling of the name, or if a path was inclu ded, verify that the path is correct and try again. At C:\emailclientbasic.ps1:18 char:23 + $mailboxExists = false <<<< + CategoryInfo : ObjectNotFound: (false:String) [], CommandNotFou ndException + FullyQualifiedErrorId : CommandNotFoundException" – Paul Masek May 23 '11 at 18:39
  • @Paul After reviewing my full script, I never pre-assign that variable. Oops. It gets true or !true when the get-mailboxpermission cmdlet returns. Undefined = !true, which helps and is why the SilentlyContinue is at the end. – sysadmin1138 May 23 '11 at 18:52
4

You could run it as a background job and then wait for that job to finish. Like this:

$enablemb = Start-Job { Enable-Mailbox -Identity "$DName" -Database "$RData" }
Wait-Job $enablemb
Receive-Job $enablemb

Jason Berg
  • 18,954
  • 6
  • 38
  • 55
  • Thanks Jason! I'm going to start looking into this and see what I can do with it. – Paul Masek May 17 '11 at 16:57
  • I tried commenting out my enable-mailbox line and substituting your recommendation. I got this error, "The term 'Enable-Mailbox' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + CategoryInfo : ObjectNotFound: (Enable-Mailbox:String) [], Comm andNotFoundException + FullyQualifiedErrorId : CommandNotFoundException" – Paul Masek May 23 '11 at 18:36
1

Start-Sleep = wait x seconds

http://technet.microsoft.com/en-us/library/ee177002.aspx

Bret Fisher
  • 3,963
  • 2
  • 20
  • 25
  • Thanks Bret, but as I told Sven, I'm looking for a more intelligent command to actually proceed when the account has been mail-enabled. A static wait time will not help in my situation. – Paul Masek May 17 '11 at 14:52
1

Why not something like:

do {
$testpath = Test-Path -path \\dns2\d$\test
}
until ($testpath -eq $true)

I use this type of command with an addtional start-sleep after the initial test because do until eats a lot of processor cycles without it. So mine looks more like this:

do {
$testpath = Test-Path -path \\dns2\d$\test
start-sleep -s 10}
until ($testpath -eq $true)

If the test is going to change state quickly when do not worry about the start-sleep.

Marko
  • 227
  • 4
  • 7
  • 15
Sean
  • 11
  • 1