locked
Powershell :MDT cmdlet doesn't seem to work properly when invoked as background job or maybe it's me ?? RRS feed

  • Question

  • Hi every one, i'm a powershell beginner and need some help to see if i understand background-job correctly. 

    I'm actually writing a powershell UI to import WIM images to MDT 2013. (I'm working on a Windows 8.1 workstation). because Operating system importation take a while, i decided to do the import as a background task to avoid UI freezing.

    If i run the import in the current session with the following code :

    $Global:DeploySharePath = "D:\[ISO]\WINDOWS81\Deploy"
    $WimDestPath = "D:\install.wim"
    $DestFolder = "Teste-Folder"
    
    Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
    Restore-MDTPersistentDrive
    Import-MDToperatingsystem -path "DS001:\Operating Systems" -SourceFile $WimDestPath -DestinationFolder $DestFolder -Verbose

    it works as expected and import correctly the new OS to MDT.

    But if i try the same as a background job, it works partially : the WIM image is imported to MDT, but some MDT information are not updated and the new OS does not show up in the MDT MMC (but files are moved to the deployment share).

    Here is what i wrote to launch the import as a background job, could someone please tell if there's something wrong in my code, or if the MDT cmdlet is broken in some way when used in a background job ?

    $Global:DeploySharePath = "D:\[ISO]\WINDOWS81\Deploy"
    $WimDestPath = "D:\install.wim"
    $DestFolder = "Teste-Folder"
    
    $job = start-job -InitializationScript {Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"} -Name MDTImport -ArgumentList $WimDestPath, $DestFolder, $Global:DeploySharePath –ScriptBlock {
    
    	Param($WimDestPath, $DestFolder, $Global:DeploySharePath)
    	Restore-MDTPersistentDrive
    	Import-MDToperatingsystem -path "DS001:\Operating Systems" -SourceFile $WimDestPath -DestinationFolder $DestFolder -Verbose
    				
    	}
    	
    	# Loop while there are running jobs
        while($job.state -ne "Completed") {
    				
    		sleep -seconds 2
    	}
    			
    	# Imorpt the resulting 
    	Receive-Job MDTImport –Keep

    Many thanks in advance

    Diagg

     

    Monday, October 28, 2013 5:56 AM

Answers

  • Hi all,

    In case anyone care, I've found the solution : there's a ".Net" way to execute background job (more infos here : http://goo.gl/mGvhaO and there : http://goo.gl/NUzCD5 ) called Runspaces. 

    Fortunately, this method works perfectly with MDT cmdlet. the solution looks now like this :

    $DeploySharePath = "D:\[ISO]\WINDOWS81\Deploy"
    $WimDestPath = "D:\install.wim"
    $DestFolder = "Teste-Folder" 
     
    $ScriptBlock = {
       Param ($DeploySharePath,$WimDestPath,$DestFolder)
       
    		Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
    		New-PSDrive -Name "MDT-001" -PSProvider MDTProvider -Root $DeploySharePath -Scope Global
    		Import-MDToperatingsystem -path "MDT-001:\Operating Systems" -SourceFile $WimDestPath -DestinationFolder $DestFolder -Verbose
    
    		}
     
    $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
    $RunspacePool.Open()
     
    $Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($DeploySharePath)
    $Job.AddArgument($WimDestPath)
    $Job.AddArgument($DestFolder)
    $Job.RunspacePool = $RunspacePool
    $finish = $Job.BeginInvoke()
     
    Write-Host "Waiting.." -NoNewline
    Do {
       Write-Host "." -NoNewline
       Start-Sleep -Seconds 1
    } While (-Not $finish.IsCompleted)
    Write-Host "All jobs completed!"

    "Oh, Thanks you Diagg, you saved my day"

    "My pleasure Diagg, you are warmly welcome !!" 


    • Marked as answer by mrdiagg Friday, November 1, 2013 9:59 AM
    • Edited by mrdiagg Friday, November 1, 2013 10:01 AM
    Friday, November 1, 2013 9:59 AM

All replies

  • I do not understand the need to make this a *Background* powershell job.

    IF you are running the OS import in a separate process, and expecting the results to show up in the MDT console without a shutdown and restart of the MDT console, this is not supported.

    If you have a perception of the Import-MDTOperatingSystem cmdlet taking too long, then my preference is to copy the OS bits to the same volume as the MDT DeploymentShare, and import the OS with the -Move switch so the process only takes a few seconds.


    Keith Garner - keithga.wordpress.com


    • Edited by Keith GarnerMVP Monday, October 28, 2013 6:54 PM
    • Proposed as answer by Keith GarnerMVP Monday, October 28, 2013 6:54 PM
    • Unproposed as answer by mrdiagg Tuesday, October 29, 2013 7:43 PM
    Monday, October 28, 2013 6:53 PM
  • Hi Keith,

    the need to run the import in the background is to keep my UI away from freezing while the OS-import occur (i have a 'marquee' progress bar that completely stop moving if the import is not run in the background) .

    I've red everywhere that it is the only way to process long task and keep your UI responsive at the same time. If any alternative method exist, please tell me.

    I know that the MDT console should be closed/open to show the imported OS and i'm ok with that.

    Also thanks for -Move switch trick, but it won't be suitable for me as my tool will work mostly over deployement share located on UEFI/Fat USB keys. So if OS image is more than 4 GO before import, i'm stuck...

    Hope this is clearer 

    If I can afford to insist, please give a try to the background job (the script should work on his own) as the way the cmdlet behave under this context is questionable to say the least. 

    I Know that you've been part of the MDT development team so you are maybe one of the best person around to tell if there's something wrong in the cmdlet or if there is something to change in my script to make the Os-import working as expected.

    Regards

    Diagg 


    • Edited by mrdiagg Monday, October 28, 2013 11:35 PM forgot something
    Monday, October 28, 2013 11:33 PM
  • Hi all,

    In case anyone care, I've found the solution : there's a ".Net" way to execute background job (more infos here : http://goo.gl/mGvhaO and there : http://goo.gl/NUzCD5 ) called Runspaces. 

    Fortunately, this method works perfectly with MDT cmdlet. the solution looks now like this :

    $DeploySharePath = "D:\[ISO]\WINDOWS81\Deploy"
    $WimDestPath = "D:\install.wim"
    $DestFolder = "Teste-Folder" 
     
    $ScriptBlock = {
       Param ($DeploySharePath,$WimDestPath,$DestFolder)
       
    		Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
    		New-PSDrive -Name "MDT-001" -PSProvider MDTProvider -Root $DeploySharePath -Scope Global
    		Import-MDToperatingsystem -path "MDT-001:\Operating Systems" -SourceFile $WimDestPath -DestinationFolder $DestFolder -Verbose
    
    		}
     
    $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
    $RunspacePool.Open()
     
    $Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($DeploySharePath)
    $Job.AddArgument($WimDestPath)
    $Job.AddArgument($DestFolder)
    $Job.RunspacePool = $RunspacePool
    $finish = $Job.BeginInvoke()
     
    Write-Host "Waiting.." -NoNewline
    Do {
       Write-Host "." -NoNewline
       Start-Sleep -Seconds 1
    } While (-Not $finish.IsCompleted)
    Write-Host "All jobs completed!"

    "Oh, Thanks you Diagg, you saved my day"

    "My pleasure Diagg, you are warmly welcome !!" 


    • Marked as answer by mrdiagg Friday, November 1, 2013 9:59 AM
    • Edited by mrdiagg Friday, November 1, 2013 10:01 AM
    Friday, November 1, 2013 9:59 AM