diff --git a/Scripts/BatchConversion/README.md b/Scripts/BatchConversion/README.md new file mode 100644 index 0000000..ec976ad --- /dev/null +++ b/Scripts/BatchConversion/README.md @@ -0,0 +1,10 @@ +A set of basic scripts that allow converting a batch of installers on a set of machines using MSIX Packaging Tool: + +Supporting scripts: +1. batch_convert.ps1 - Dispatch work to target machines +2. sign_deploy_run.ps1 - Sign resulting packages +3. run_job.ps1 - Attempt to run the packages locally for initial validation + +Usage: +Edit the file entry.ps1 with the parameters of your virtual/remote machines and installers you would like to convert. +Run: entry.ps1 diff --git a/Scripts/BatchConversion/Readme.txt b/Scripts/BatchConversion/Readme.txt deleted file mode 100644 index 73bb22c..0000000 --- a/Scripts/BatchConversion/Readme.txt +++ /dev/null @@ -1,6 +0,0 @@ - -A set of basic scripts that: - -1. batch_convert.ps1 - Dispatch work to target machines -2. sign_deploy_run.ps1 - Sign resulting packages -3. run_job.ps1 - Attempt to run the packages locally for initial validation diff --git a/Scripts/BatchConversion/batch_convert.ps1 b/Scripts/BatchConversion/batch_convert.ps1 index 6a80d5a..3ec328e 100644 --- a/Scripts/BatchConversion/batch_convert.ps1 +++ b/Scripts/BatchConversion/batch_convert.ps1 @@ -62,47 +62,47 @@ function RunConversionJobs($conversionsParameters, $virtualMachines, $remoteMach # Next schedule jobs on virtual machines which can be checkpointed/re-used # keep a mapping of VMs and the current job they're running, initialized ot null - # $vmsCurrentJobMap = @{} - # $virtualMachines | Foreach-Object { $vmsCurrentJobMap.Add($_.Name, $nul) } + $vmsCurrentJobMap = @{} + $virtualMachines | Foreach-Object { $vmsCurrentJobMap.Add($_.Name, $nul) } - # # Use a semaphore to signal when a machine is available. Note we need a global semaphore as the jobs are each started in a different powershell process - # $semaphore = New-Object -TypeName System.Threading.Semaphore -ArgumentList @($virtualMachines.Count, $virtualMachines.Count, "Global\MPTBatchConversion") + # Use a semaphore to signal when a machine is available. Note we need a global semaphore as the jobs are each started in a different powershell process + $semaphore = New-Object -TypeName System.Threading.Semaphore -ArgumentList @($virtualMachines.Count, $virtualMachines.Count, "Global\MPTBatchConversion") - # while ($semaphore.WaitOne(-1)) - # { - # if ($remainingConversions.Count -gt 0) - # { - # # select a job to run - # Write-Host "Determining next job to run..." - # $conversionParam = $conversionsParameters[$remainingConversions[0]] - # # select a VM to run it on. Retry a few times due to race between semaphore signaling and process completion status - # $vm = $nul - # while (-not $vm) { $vm = $virtualMachines | where { -not($vmsCurrentJobMap[$_.Name]) -or -not($vmsCurrentJobMap[$_.Name].ExitCode -eq $Nul) } | Select-Object -First 1 } - # Write-Host "Dequeuing conversion job for installer $($conversionParam.InstallerPath) on VM $($vm.Name)" + while ($semaphore.WaitOne(-1)) + { + if ($remainingConversions.Count -gt 0) + { + # select a job to run + Write-Host "Determining next job to run..." + $conversionParam = $conversionsParameters[$remainingConversions[0]] + # select a VM to run it on. Retry a few times due to race between semaphore signaling and process completion status + $vm = $nul + while (-not $vm) { $vm = $virtualMachines | where { -not($vmsCurrentJobMap[$_.Name]) -or -not($vmsCurrentJobMap[$_.Name].ExitCode -eq $Nul) } | Select-Object -First 1 } + Write-Host "Dequeuing conversion job for installer $($conversionParam.InstallerPath) on VM $($vm.Name)" - # # Capture the job index and update list of remaining conversions to run - # $jobId = $remainingConversions[0] - # $remainingConversions = $remainingConversions | where { $_ -ne $remainingConversions[0] } + # Capture the job index and update list of remaining conversions to run + $jobId = $remainingConversions[0] + $remainingConversions = $remainingConversions | where { $_ -ne $remainingConversions[0] } - # $templateFilePath = CreateMPTTemplate $conversionParam $jobId $vm $nul $workingDirectory - # $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vm.Credential.Password) - # $password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) + $templateFilePath = CreateMPTTemplate $conversionParam $jobId $vm $nul $workingDirectory + $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vm.Credential.Password) + $password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) - # $process = Start-Process "powershell.exe" -ArgumentList($runJobScriptPath, "-jobId", $jobId, "-vmName", $vm.Name, "-vmsCount", $virtualMachines.Count, "-machinePassword", $password, "-templateFilePath", $templateFilePath, "-initialSnapshotName", $initialSnapshotName) -PassThru - # $vmsCurrentJobMap[$vm.Name] = $process - # } - # else - # { - # $semaphore.Release() - # break; - # } + $process = Start-Process "powershell.exe" -ArgumentList($runJobScriptPath, "-jobId", $jobId, "-vmName", $vm.Name, "-vmsCount", $virtualMachines.Count, "-machinePassword", $password, "-templateFilePath", $templateFilePath, "-initialSnapshotName", $initialSnapshotName) -PassThru + $vmsCurrentJobMap[$vm.Name] = $process + } + else + { + $semaphore.Release() + break; + } - # Sleep(1) - # } + Sleep(1) + } - #Write-Host "Finished scheduling all jobs" - #$virtualMachines | foreach-object { if ($vmsCurrentJobMap[$_.Name]) { $vmsCurrentJobMap[$_.Name].WaitForExit() } } - #$semaphore.Dispose() + Write-Host "Finished scheduling all jobs" + $virtualMachines | foreach-object { if ($vmsCurrentJobMap[$_.Name]) { $vmsCurrentJobMap[$_.Name].WaitForExit() } } + $semaphore.Dispose() Read-Host -Prompt 'Press any key to continue ' Write-Host "Finished running all jobs" } \ No newline at end of file diff --git a/Scripts/BatchConversion/entry.ps1 b/Scripts/BatchConversion/entry.ps1 index 1fcb5f4..e440f1f 100644 --- a/Scripts/BatchConversion/entry.ps1 +++ b/Scripts/BatchConversion/entry.ps1 @@ -7,12 +7,12 @@ $credential = Get-Credential $virtualMachines = @( - # @{ Name = "vm1"; Credential = $credential } - # @{ Name = "vm2"; Credential = $credential } + @{ Name = "vm1"; Credential = $credential } + @{ Name = "vm2"; Credential = $credential } ) $remoteMachines = @( - # @{ ComputerName = "YourVMNameHere.westus.cloudapp.azure.com"; Credential = $credential } + @{ ComputerName = "YourVMNameHere.westus.cloudapp.azure.com"; Credential = $credential } ) $conversionsParameters = @( @@ -23,23 +23,23 @@ $conversionsParameters = @( PublisherName = "CN=YourCompany"; PublisherDisplayName = "YourCompany"; PackageVersion = "1.0.0.0" - }#, - #@{ - # InstallerPath = "Path\To\Your\Installer\YourInstaller2.msi"; - # PackageName = "YourApp2"; - # PackageDisplayName = "Your App2"; - # PublisherName = "CN=YourCompany"; - # PublisherDisplayName = "YourCompany"; - # PackageVersion = "1.0.0.0" - #}, - #@{ - # InstallerPath = "Path\To\Your\Installer\YourInstaller3.msi"; - # PackageName = "YourApp3"; - # PackageDisplayName = "Your App3"; - # PublisherName = "CN=YourCompany"; - # PublisherDisplayName = "YourCompany"; - # PackageVersion = "1.0.0.0" - #} + }, + @{ + InstallerPath = "Path\To\Your\Installer\YourInstaller2.msi"; + PackageName = "YourApp2"; + PackageDisplayName = "Your App2"; + PublisherName = "CN=YourCompany"; + PublisherDisplayName = "YourCompany"; + PackageVersion = "1.0.0.0" + }, + @{ + InstallerPath = "Path\To\Your\Installer\YourInstaller3.msi"; + PackageName = "YourApp3"; + PackageDisplayName = "Your App3"; + PublisherName = "CN=YourCompany"; + PublisherDisplayName = "YourCompany"; + PackageVersion = "1.0.0.0" + } ) $workingDirectory = [System.IO.Path]::Combine($PSScriptRoot, "out") diff --git a/Scripts/BatchConversion/sign_deploy_run.ps1 b/Scripts/BatchConversion/sign_deploy_run.ps1 index 231f436..34e0e43 100644 --- a/Scripts/BatchConversion/sign_deploy_run.ps1 +++ b/Scripts/BatchConversion/sign_deploy_run.ps1 @@ -1,8 +1,5 @@ function SignAndDeploy($msixFolder) { - Get-AppxPackage *YourApp* | Remove-AppxPackage - Get-AppxPackage *YourApp2* | Remove-AppxPackage - Get-AppxPackage *YourApp3* | Remove-AppxPackage Get-ChildItem $msixFolder | foreach-object { $pfxFilePath = "\\Path\To\Your\Certificate\YourCert.pfx"