locked
While loop alternative RRS feed

  • Question

  • Currently I have a powershell script that I use to create new users.  In the script I have a few while loops to wait until parts of the user setup are complete and here are the steps I am performing:
    Fill out a form on SharePoint and trigger a flow to azure automation.
    Create a user onprem in AD
    Wait until the user is visible in AD and force a ADSync
    Wait until the user is visible in Azure AD and assign licenses
    Wait until the user is visible in Exchange Online and create the remote mailbox link back onprem
    Wait until the user is visible in Skype and assign a phone number
    Here is an example of the while loop that I do to wait:
    $onPremUser= Get-aduser $userName
    while ($onPremUser -eq $null){
    if($checkUser -le '10'){
    $checkUser++
    Start-Sleep -s 10
    $onPremUser= Get-aduser $userName
        }else{
        Throw "Can't find User in AD"
        }
    }

    I run this script in hybrid Azure Automation and if one of these loops fails, I cause a lot of manual steps to finish creating the user.  What is the best way to break these up into chunks so if it does fail, I can continue at a later time from that point.  PowerShell workflow? Logic app? Flow?


    Monday, October 15, 2018 6:12 PM

All replies

  • Your question is unanswerable.  There is not enough information and it is unclear why you think you have to wait.  There is no need to wait on user creation.  Just use "-PassThru" to get a copy of the new user object and continue the setup.

    $newuser = New-AdUser …. -PassThru

    Your "if" is incorrect. You cannot test a numeric range against a string.

    if($checkUser -le '10'){

    should be

    if($checkUser -le 10){


    \_(ツ)_/

    Monday, October 15, 2018 6:20 PM
  • Actually, I do have to wait (I just put a piece of my code in as an example of how I wait)

    My question is:

    How can I start where I left off if my script stops on a while loop?

    OR

    If a while loop is not the best idea (which I am feeling it isn't based on my scenario) What should be my best approach to perform the tasks listed above.

    Monday, October 15, 2018 6:28 PM
  • On New-AdUser you do not have to wait.  The account has been created and is ready immediately at the termination of the command.  The returned user object can now be used for anything you need to do with it.  That is the whole point of "-PassThru".

    When retrieving new objects from the cloud you can just try in a loop with a sleep until the object is available, In a properly synced system this should only be a few seconds.

    do{
         Sleep 2
    }
    until($azUser = Get-AzRmAdUser $newuser.SamAccountNAme)

    When the object is returned the loop will terminate.


    \_(ツ)_/


    • Edited by jrv Monday, October 15, 2018 6:35 PM
    Monday, October 15, 2018 6:35 PM
  • In a properly synced system this should only be a few seconds.

    While that may be true in a single server, single-site, single-domain forest, it probably isn't true in more complex AD forests. Inter-site AD replication may take place at relatively long (say, 15 minute) intervals, and may be scheduled to run at intervals of several hours (or more). Even within a multiple-DC site the replication may seem like an eternity (e.g. 5 minutes between DCs) while waiting replication to complete.

    Also, without specifying a particular DC, each New-ADUser execution in a multi-DC site may be picking a different DC.

    One way to avoid some of the delay is to specify one server on the cmdlets which perform the operations, preferably a server within the site that sources the Azure replication.

    I'd also suggest that the OP creates all the AD users first, and then start the remainder of the processing (e.g., waiting until all the users appear on the replication server before forcing the sync).

    Your DO-UNTIL would handle the waiting for the replication to complete for each individual user, and can be used for both the on-prem (using get-aduser against the Azure sync source DC) and remote waiting-for-replication.



    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Monday, October 15, 2018 7:41 PM
  • You are correct Rich...actually the issue really hasn't to do with whether or not there is a delay...more so if one of the sections fails (because of too long of  a delay..or other reasons).  I think I have a solution though....powershell workflow with checkpoints.  I have never used this feature before but reading up on it, I think it will cover me.  So if one of my wait areas fails....like mailbox creation (maybe MS has a temp outage with exchange online) I believe checkpoints in powershell will allow me to resume and rerun from a certain checkpoint.

    JRV, thanks as well...the do until looks much cleaner than my while loop.  The one concern I have with do until, what if I only want the "do until" to run for a maximum of 15 min? 

    Monday, October 15, 2018 7:52 PM
  • $stopwatch =  [system.diagnostics.stopwatch]::StartNew()
    do{
        if($stopwatch.Elapsed -gt [timespan]'00:15'){break}
        Sleep 5
    }
    until($azUser = Get-AzRmAdUser $newuser.SamAccountNAme)

    Yes.  A workflow would be a good solution but can create issues with remoting.


    \_(ツ)_/


    Monday, October 15, 2018 8:07 PM
  • In a properly synced system this should only be a few seconds.

    While that may be true in a single server, single-site, single-domain forest, it probably isn't true in more complex AD forests. Inter-site AD replication may take place at relatively long (say, 15 minute) intervals, and may be scheduled to run at intervals of several hours (or more). Even within a multiple-DC site the replication may seem like an eternity (e.g. 5 minutes between DCs) while waiting replication to complete.

    Also, without specifying a particular DC, each New-ADUser execution in a multi-DC site may be picking a different DC.

    One way to avoid some of the delay is to specify one server on the cmdlets which perform the operations, preferably a server within the site that sources the Azure replication.

    I'd also suggest that the OP creates all the AD users first, and then start the remainder of the processing (e.g., waiting until all the users appear on the replication server before forcing the sync).

    Your DO-UNTIL would handle the waiting for the replication to complete for each individual user, and can be used for both the on-prem (using get-aduser against the Azure sync source DC) and remote waiting-for-replication.



    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Doesn't matter.  If you want to work with the account object it doesn't matter if replication is incomplete since "PassThru" gives you back a full built object.  This prevents trying to access an object on a different DC and having that DC not updated.  The initial object can always be used for updates with Set-AdUser or for any other thing you need to use the account object for.  This is fundamental to the design of AD.  It is built into the API and has little to do with PowerShell.

    Waiting for the account to be complete in Azure is another matter and must be queried separately directly to Azure.  There are also other methods of checking replication status locally and to Azure.  They can also make coding this much easier.

    Once AD has replicated to AzureAD then all other operations on separate subsystems like Skype can be done in parallel without the need to wait although full provisioning of SharePoint can be dependent on Exchange.  MS has been doing a good job of decpouplng these provisioning issues and I suspect that all can be done in parallel now after AzureAD is finished.


    \_(ツ)_/


    • Edited by jrv Monday, October 15, 2018 8:16 PM
    Monday, October 15, 2018 8:14 PM