ICT-Autopilot.ps1
<#PSScriptInfo .VERSION 2.2.1 .GUID 1522f19a-667a-4638-8def-7d5590a61094 .AUTHOR a.twist@imperial.ac.uk .COMPANYNAME Imperial College London .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Checks if an ICT laptop is already enrolled in Autopilot #> ##### ## Imperial College London ## ----------------------- ## Enrolement script ## ##### ### ## This uses the microsoft script that's available here ## https://www.powershellgallery.com/packages/Get-WindowsAutoPilotInfo/3.5 function get-WindowsAutoPilotInfo { [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Position=0)][alias("DNSHostName","ComputerName","Computer")] [String[]] $Name = @("localhost"), [Parameter(Mandatory=$False)] [String] $OutputFile = "", [Parameter(Mandatory=$False)] [String] $GroupTag = "", [Parameter(Mandatory=$False)] [String] $AssignedUser = "", [Parameter(Mandatory=$False)] [Switch] $Append = $false, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $Credential = $null, [Parameter(Mandatory=$False)] [Switch] $Partner = $false, [Parameter(Mandatory=$False)] [Switch] $Force = $false, [Parameter(Mandatory=$True,ParameterSetName = 'Online')] [Switch] $Online = $false, [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [String] $TenantId = "", [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [String] $AppId = "", [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [String] $AppSecret = "", [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [String] $AddToGroup = "", [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [String] $AssignedComputerName = "", [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [Switch] $Assign = $false, [Parameter(Mandatory=$False,ParameterSetName = 'Online')] [Switch] $Reboot = $false ) Begin { # Initialize empty list $computers = @() # If online, make sure we are able to authenticate if ($Online) { # Get NuGet $provider = Get-PackageProvider NuGet -ErrorAction Ignore if (-not $provider) { Write-Host "Installing provider NuGet" Find-PackageProvider -Name NuGet -ForceBootstrap -IncludeDependencies } # Get WindowsAutopilotIntune module (and dependencies) $module = Import-Module WindowsAutopilotIntune -PassThru -ErrorAction Ignore if (-not $module) { Write-Host "Installing module WindowsAutopilotIntune" Install-Module WindowsAutopilotIntune -Force } Import-Module WindowsAutopilotIntune -Scope Global # Get Graph Authentication module (and dependencies) $module = Import-Module microsoft.graph.authentication -PassThru -ErrorAction Ignore if (-not $module) { Write-Host "Installing module microsoft.graph.authentication" Install-Module microsoft.graph.authentication -Force } Import-Module microsoft.graph.authentication -Scope Global # Get required modules for AddToGroup switch if ($AddToGroup) { $module = Import-Module Microsoft.Graph.Groups -PassThru -ErrorAction Ignore if (-not $module) { Write-Host "Installing module Microsoft.Graph.Groups" Install-Module Microsoft.Graph.Groups -Force } $module = Import-Module Microsoft.Graph.Identity.DirectoryManagement -PassThru -ErrorAction Ignore if (-not $module) { Write-Host "Installing module Microsoft.Graph.Identity.DirectoryManagement" Install-Module Microsoft.Graph.Identity.DirectoryManagement -Force } } # Connect if ($AppId -ne "") { $graph = Connect-MSGraphApp -Tenant $TenantId -AppId $AppId -AppSecret $AppSecret Write-Host "... Connected to Intune tenant $TenantId using app-based authentication (Azure AD authentication not supported)" -ForegroundColor "darkcyan" } else { # Connect-MgGraph -Scopes "DeviceManagementServiceConfig.ReadWrite.All", "Device.ReadWrite.All", "Group.ReadWrite.All" | out-null Connect-MgGraph -Scopes "DeviceManagementServiceConfig.ReadWrite.All", "DeviceManagementManagedDevices.ReadWrite.All", "Device.ReadWrite.All", "Group.ReadWrite.All", "GroupMember.ReadWrite.All" $graph = Get-MgContext Write-Host "... Connected to Intune tenant" -ForegroundColor "darkcyan" $graph.TenantId } # Force the output to a file if ($OutputFile -eq "") { $OutputFile = "$($env:TEMP)\autopilot.csv" } } } Process { foreach ($comp in $Name) { $bad = $false # Get a CIM session if ($comp -eq "localhost") { $session = New-CimSession } else { $session = New-CimSession -ComputerName $comp -Credential $Credential } # Get the common properties. Write-Verbose "Checking $comp" $serial = (Get-CimInstance -CimSession $session -Class Win32_BIOS).SerialNumber # Get the hash (if available) $devDetail = (Get-CimInstance -CimSession $session -Namespace root/cimv2/mdm/dmmap -Class MDM_DevDetail_Ext01 -Filter "InstanceID='Ext' AND ParentID='./DevDetail'") if ($devDetail -and (-not $Force)) { $hash = $devDetail.DeviceHardwareData } else { $bad = $true $hash = "" } # If the hash isn't available, get the make and model if ($bad -or $Force) { $cs = Get-CimInstance -CimSession $session -Class Win32_ComputerSystem $make = $cs.Manufacturer.Trim() $model = $cs.Model.Trim() if ($Partner) { $bad = $false } } else { $make = "" $model = "" } # Getting the PKID is generally problematic for anyone other than OEMs, so let's skip it here $product = "" # Depending on the format requested, create the necessary object if ($Partner) { # Create a pipeline object $c = New-Object psobject -Property @{ "Device Serial Number" = $serial "Windows Product ID" = $product "Hardware Hash" = $hash "Manufacturer name" = $make "Device model" = $model } # From spec: # "Manufacturer Name" = $make # "Device Name" = $model } else { # Create a pipeline object $c = New-Object psobject -Property @{ "Device Serial Number" = $serial "Windows Product ID" = $product "Hardware Hash" = $hash } if ($GroupTag -ne "") { Add-Member -InputObject $c -NotePropertyName "Group Tag" -NotePropertyValue $GroupTag } if ($AssignedUser -ne "") { Add-Member -InputObject $c -NotePropertyName "Assigned User" -NotePropertyValue $AssignedUser } } # Write the object to the pipeline or array if ($bad) { # Report an error when the hash isn't available Write-Error -Message "Unable to retrieve device hardware data (hash) from computer $comp" -Category DeviceError } elseif ($OutputFile -eq "") { $c } else { $computers += $c Write-Host "... Gathered details for device with serial number: " -ForegroundColor "darkcyan" -nonewline; write-host "$serial" -ForegroundColor "green" } Remove-CimSession $session } } End { if ($OutputFile -ne "") { if ($Append) { if (Test-Path $OutputFile) { $computers += Import-CSV -Path $OutputFile } } if ($Partner) { $computers | Select-Object "Device Serial Number", "Windows Product ID", "Hardware Hash", "Manufacturer name", "Device model" | ConvertTo-CSV -NoTypeInformation | ForEach-Object {$_ -replace '"',''} | Out-File $OutputFile } elseif ($AssignedUser -ne "") { $computers | Select-Object "Device Serial Number", "Windows Product ID", "Hardware Hash", "Group Tag", "Assigned User" | ConvertTo-CSV -NoTypeInformation | ForEach-Object {$_ -replace '"',''} | Out-File $OutputFile } elseif ($GroupTag -ne "") { $computers | Select-Object "Device Serial Number", "Windows Product ID", "Hardware Hash", "Group Tag" | ConvertTo-CSV -NoTypeInformation | ForEach-Object {$_ -replace '"',''} | Out-File $OutputFile } else { $computers | Select-Object "Device Serial Number", "Windows Product ID", "Hardware Hash" | ConvertTo-CSV -NoTypeInformation | ForEach-Object {$_ -replace '"',''} | Out-File $OutputFile } } if ($Online) { # Add the devices $importStart = Get-Date $imported = @() $computers | ForEach-Object { $imported += Add-AutopilotImportedDevice -serialNumber $_.'Device Serial Number' -hardwareIdentifier $_.'Hardware Hash' -groupTag $_.'Group Tag' -assignedUser $_.'Assigned User' } # Wait until the devices have been imported $processingCount = 1 while ($processingCount -gt 0) { $current = @() $processingCount = 0 $imported | ForEach-Object { $device = Get-AutopilotImportedDevice -id $_.id if ($device.state.deviceImportStatus -eq "unknown") { $processingCount = $processingCount + 1 } $current += $device } $deviceCount = $imported.Length Write-Host "... Waiting for $processingCount of $deviceCount to be imported" -ForegroundColor "darkcyan" if ($processingCount -gt 0){ Start-Sleep 30 } } $importDuration = (Get-Date) - $importStart $importSeconds = [Math]::Ceiling($importDuration.TotalSeconds) $successCount = 0 $current | ForEach-Object { Write-Host "$($device.serialNumber): $($device.state.deviceImportStatus) $($device.state.deviceErrorCode) $($device.state.deviceErrorName)" if ($device.state.deviceImportStatus -eq "complete") { $successCount = $successCount + 1 } } Write-Host "... $successCount devices imported successfully. Elapsed time to complete import: $importSeconds seconds" -ForegroundColor "darkcyan" # Wait until the devices can be found in Intune (should sync automatically) $syncStart = Get-Date $processingCount = 1 while ($processingCount -gt 0) { $autopilotDevices = @() $processingCount = 0 $current | ForEach-Object { if ($device.state.deviceImportStatus -eq "complete") { $device = Get-AutopilotDevice -id $_.state.deviceRegistrationId if (-not $device) { $processingCount = $processingCount + 1 } $autopilotDevices += $device } } $deviceCount = $autopilotDevices.Length Write-Host "... Waiting for $processingCount of $deviceCount to be synced" -ForegroundColor "darkcyan" if ($processingCount -gt 0){ Start-Sleep 30 } } $syncDuration = (Get-Date) - $syncStart $syncSeconds = [Math]::Ceiling($syncDuration.TotalSeconds) Write-Host "... All devices synced. Elapsed time to complete sync: $syncSeconds seconds" -ForegroundColor "Green" # Add the device to the specified AAD group if ($AddToGroup) { $aadGroup = Get-MgGroup -Filter "DisplayName eq '$AddToGroup'" if ($aadGroup) { $autopilotDevices | ForEach-Object { $aadDevice = Get-MgDevice -Search "deviceId:$($_.azureActiveDirectoryDeviceId)" -ConsistencyLevel eventual if ($aadDevice) { Write-Host "Adding device $($_.serialNumber) to group $AddToGroup" New-MgGroupMember -GroupId $($aadGroup.Id) -DirectoryObjectId $($aadDevice.Id) Write-Host "Added devices to group '$AddToGroup' $($aadGroup.Id)" } else { Write-Error "Unable to find Azure AD device with ID $($_.azureActiveDirectoryDeviceId)" } } } else { Write-Error "Unable to find group $AddToGroup" } } # Assign the computer name if ($AssignedComputerName -ne "") { $autopilotDevices | ForEach-Object { Set-AutopilotDevice -id $_.id -displayName $AssignedComputerName } } # Wait for assignment (if specified) if ($Assign) { $assignStart = Get-Date $processingCount = 1 while ($processingCount -gt 0) { $processingCount = 0 $autopilotDevices | ForEach-Object { $device = Get-AutopilotDevice -id $_.id -Expand if (-not ($device.deploymentProfileAssignmentStatus.StartsWith("assigned"))) { $processingCount = $processingCount + 1 } } $deviceCount = $autopilotDevices.Length Write-Host "... Waiting for $processingCount of $deviceCount to be assigned" -ForegroundColor "darkcyan" if ($processingCount -gt 0){ Start-Sleep 30 } } $assignDuration = (Get-Date) - $assignStart $assignSeconds = [Math]::Ceiling($assignDuration.TotalSeconds) Write-Host "... Profiles assigned to all devices. Elapsed time to complete assignment: $assignSeconds seconds" -ForegroundColor "Green" if ($Reboot) { Restart-Computer -Force } } } } } clear write-host "/---------------------------------------------------------\" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " This tool will check to see if a machine is enrolled in " -foreground "yellow" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " Autopilot and enrol if it is required " -foreground "yellow" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host "---------------------------------------------------------" -foreground "darkcyan" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " V2.2.1 " -foreground "blue" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " Please contact EUC with any questions " -foreground "yellow" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " e-mail us at: icteucteam@imperial.ac.uk " -foreground "yellow" -nonewline; write-host "|" -foreground "darkcyan" write-host "|" -foreground "darkcyan" -nonewline; write-host " Or contact us on Teams " -foreground "yellow" -nonewline; write-host "|" -foreground "darkcyan" write-host "\---------------------------------------------------------/" -foreground "darkcyan" write-host "" write-host "" write-host "YOU DO NOT NEED TO RUN THIS SCRIPT IF THE PC IS FRESH OUT OF THE BOX FROM HP" -ForegroundColor "DarkBlue" -BackgroundColor "gray" write-host "IT WILL ALREADY HAVE BEEN PRE-PROVISIONED, THE USER SIMPLY NEEDS TO COMPLETE THE SETUP" -ForegroundColor "darkblue" -BackgroundColor "gray" # write-host "" write-host "ALSO, IF THE MACHINE IS ALREADY ENROLLED IN AUTOPILOT THEN YOU DO NOT NEED TO RUN THIS SCRIPT" -ForegroundColor "DarkBlue" -BackgroundColor "gray" # write-host "" write-host " " write-host "1. Enroll this machine in Autopilot" -foreground "yellow" write-host "2. Create Enrolment CSV that can be imported via Intune" -foreground "yellow" write-host "3. Run Windows Update to install all drivers and updates" -foreground "yellow" write-host " (Only do this if you wiped the machine and rebuilt with a USB stick)" -foreground "yellow" write-host "4. Display machine Information" -foreground "yellow" write-host "5. Reboot computer" -foreground "yellow" write-host "6. Totally delete machine from Autopilot, Intune and Entra ID (AzureAD)" -foreground "yellow" write-host " (We recommend you use Option 6 when a machine gives a Red Screen after failing Autopilot Pre-Provision)" -foreground "yellow" write-host " " write-host " " $input = Read-Host -Prompt 'Please choose an option (enter a number)' write-host " " write-host " " if ($input -eq '3') { Write-host "...This tool will now download and install all available drivers and updates for this laptop" Write-host "...It will then REBOOT the machine and start Windows Setup (OOBE)" Write-host "...If you still need to enrol the machine in Autopilot, then run the ICT-Autopilot script" write-host "...again after the reboot" write-host "...Are you 100% sure you want to continue (Y/N) " -foregroundcolor "yellow" $response = read-host if ( $response -ne "Y" ) { exit } set-psrepository psgallery -installationpolicy trusted Install-Module PSWindowsUpdate -force set-executionpolicy remotesigned Get-WindowsUpdate -AcceptAll -Install -AutoReboot exit } if ($input -eq '4') { $info = Get-ComputerInfo $OS = ($info).windowsproductname # Windows 11 only - $build = ($info).OSDisplayVersion $model = ($info).csmodel $proc = (($info).CsProcessors).name $PysicalMemory = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb $physmem = "$PysicalMemory GB" $bios = ($info).BiosSMBIOSBIOSVersion $locale = ($info).OsLanguage $serial = ($info).BiosSeralNumber try { $assettag = (Get-WmiObject Win32_SystemEnclosure).SMBiosAssetTag } catch { $assettag = "Asset Tag not in BIOS" } Write-host "Operating System - " -foregroundcolor "white" -nonewline; write-host "$os" -foregroundcolor "cyan" Write-host "Model - " -foregroundcolor "white" -nonewline; write-host "$model" -foregroundcolor "cyan" Write-host "Processor - " -foregroundcolor "white" -nonewline; write-host "$proc" -foregroundcolor "cyan" Write-host "Memory - " -foregroundcolor "white" -nonewline; write-host "$physmem" -foregroundcolor "cyan" Write-host "BIOS Version - " -foregroundcolor "white" -nonewline; write-host "$bios" -foregroundcolor "cyan" Write-host "OS Locale - " -foregroundcolor "white" -nonewline; write-host "$locale" -foregroundcolor "cyan" Write-host "Serial Number - " -foregroundcolor "white" -nonewline; write-host "$serial" -foregroundcolor "cyan" Write-host "Asset Tag - " -foregroundcolor "white" -nonewline; write-host "$Assettag" -foregroundcolor "cyan" write-host "" exit } if ($input -eq '2') { ## Checking TPM version if ((Get-Tpm).ManufacturerVersionFull20) { $Tpm20 = -not (Get-Tpm).ManufacturerVersionFull20.Contains("not supported") } else { $Tpm20 = $false } $TPMGET = tpmtool getdeviceinformation $pattern = "-TPM Spec Version*" $spectemp = $TPMGET -split "`r?`n" | Select-String -Pattern $pattern $Spec = $spectemp -replace ".*:" $spec = $spec.trim() Write-host "... Checking TPM version" -ForegroundColor "darkcyan" if ($tpm20 -eq "true") { Write-host "... Laptop has" -ForegroundColor "darkcyan" -nonewline; write-host " TPM 2.0 " -ForegroundColor "Green" -nonewline; write-host "you may carry on" -ForegroundColor "darkcyan" } else { Write-host "... This laptop does NOT have TPM 2.0, please upgrade the BIOS and start again" -ForegroundColor "red" Write-host "... Exiting script" -ForegroundColor "red" exit } ## Checking Windows Edition $osedition = (Get-WmiObject -class Win32_OperatingSystem).Caption Write-host "... Checking whether laptop is running Windows Enterprise or Pro" -ForegroundColor "darkcyan" if ($osedition -like '*home*') { Write-host "... This machine is running $osedition, you need to be on Professional or Enterprise" -ForegroundColor "red" Write-host "... Please Upgrade and try again" -ForegroundColor "red" Write-host "... Exiting script" -ForegroundColor "red" exit } else { Write-host "... This machine is running " -ForegroundColor "darkcyan" -nonewline; write-host "$osedition" -ForegroundColor "Green" -nonewline; write-host " which is supported by Autopilot" -ForegroundColor "darkcyan" } ## Checking Windows build is 1803 or higher Write-host "... Checking whether Windows is 1803 or higher" -ForegroundColor "darkcyan" $buildnum = (([Environment]::OSVersion).version).build if ($buildnum -ge "17134") { Write-host "... The Windows build is " -ForegroundColor "darkcyan" -nonewline; write-host "$buildnum" -ForegroundColor "Green" -nonewline; write-host " which is supported by Autopilot" -ForegroundColor "darkcyan" } else { Write-host "... The Windows build is $buildnum which is not supported by Autopilot" -ForegroundColor "red" Write-host "... Please Upgrade Windows to a newer version to continue" -ForegroundColor "red" exit } ## Running the Get-WindowsAutopilotInfo script if (!(test-path -path "c:\temp")) { new-item -path "c:\" -name "temp" -ItemType "directory" } Set-Location -Path "C:\temp" $serial = Get-WmiObject win32_bios | select serialnumber -ExpandProperty serialnumber write-host "... Your CSV file will be created in c:\temp" -ForegroundColor "darkcyan" write-host "... Go to Intune and use the CSV to enrol the device into Autopilot" -ForegroundColor "darkcyan" Get-WindowsAutopilotInfo -OutputFile c:\temp\$serial.csv if (test-path -path "c:\temp\$serial.csv") { Write-host "... $serial.csv created in c:\temp" -ForegroundColor "green" exit } else { write-host "... export failed" -ForegroundColor "red" exit } } if ($input -eq '5') { write-host "... This will instantly reboot your computer" -ForegroundColor "darkcyan" write-host "... Are you 100% sure you want to reboot? (Y/N) " -foregroundcolor "darkcyan" $response = read-host if ( $response -ne "Y" ) { exit } shutdown /f /r /t 1 } if ($input -eq '6') { write-host " " write-host "a. Delete the machine you are currently on." -foreground "yellow" write-host "b. Delete another machine" -foreground "yellow" $input = Read-Host -Prompt 'Please choose an option (enter a letter)' write-host " " write-host " " if ($input -eq 'a') { write-host "... Getting local Serial Number" -foreground "darkcyan" $info = Get-ComputerInfo $serial = ($info).BiosSeralNumber } if ($input -eq 'b') { $serial = Read-Host -Prompt "Please enter the Serial number of the device which you wish to delete" write-host "The serial number you entered is $serial is this correct (Y/N)?" -ForegroundColor "yellow" $response = read-host if ( $response -ne "Y" ) { exit } } write-host "... Installing MSGraph Modules" -ForegroundColor "darkcyan" write-host "... This may take a short while" -ForegroundColor "darkcyan" install-module Microsoft.Graph.DeviceManagement -force install-module Microsoft.Graph.intune -force install-module microsoft.graph.beta.devicemanagement.enrollment -force install-module azuread -force connect-mggraph -nowelcome connect-azuread connect-msgraph # Delete from intune write-host "... Getting Intune machine data" -ForegroundColor "darkcyan" $info = Get-ComputerInfo $name = (Get-IntuneManagedDevice -filter ("serialnumber eq '$serial'")).devicename $IntuneID = (Get-MgDeviceManagementManagedDevice -Filter "devicename eq '$name'").id write-host "... This will 100% delete $serial from Entra ID, Intune and Autopilot Enrolment" -foregroundcolor "yellow" write-host "... Are you 100% sure you want to continue (Y/N) " -foregroundcolor "yellow" $response = read-host if ( $response -ne "Y" ) { exit } write-host "... Deleting machine from Intune" -ForegroundColor "darkcyan" Remove-MgDeviceManagementManagedDevice -ManagedDeviceId $intuneid write-host "... waiting for 60 seconds to allow time for device to delete" -ForegroundColor "darkcyan" Start-Sleep -Seconds 60 #check if machine has been deleted write-host "... Confirming deletion" -ForegroundColor "darkcyan" $delcheck = Get-MgDeviceManagementManagedDevice -Filter "devicename eq '$name'" if ($delcheck -eq $null) { write-host "... $name has been successfully deleted from Intune" -ForegroundColor "green" } else { Write-Host "... $name has NOT been deleted from Intune" -ForegroundColor "red" } # Delete from Autopilot write-host "... Deleting from Autopilot Enrolment" -ForegroundColor "darkcyan" $AutopilotDevice = Get-MgBetaDeviceManagementWindowsAutopilotDeviceIdentity -Filter "contains(serialNumber,'$($serial)')" -ErrorAction Stop try { $Result = Remove-MgDeviceManagementWindowsAutopilotDeviceIdentity -WindowsAutopilotDeviceIdentityId $AutopilotDevice.Id -PassThru -ErrorAction Stop If ($Result -eq $true) { write-host "... $name has been successfully deleted from Autopilot Enrolment" -ForegroundColor "green" } else { Write-Host "... $name has NOT been deleted from Autopilot Enrolment" -ForegroundColor "red" } } catch { Write-Host "... Error attempting to delete machine" -ForegroundColor Red Write-Error "$($_.Exception.Message)" } # Delete from Azure AD write-host "... Deleting from Entra ID" -ForegroundColor "darkcyan" write-host "... Getting Machine details" -ForegroundColor "darkcyan" $AzureAD = Get-AzureADDevice -filter ("displayname eq '$name'") foreach ($device in $azuread) { $deviceid = $device.objectid write-host "... Deleting machine with object id of $deviceid" -ForegroundColor "darkcyan" Remove-AzureADDevice -ObjectId "$deviceid" write-host "... Sleeping for 30 seconds to confirm deletion" -ForegroundColor "darkcyan" Start-Sleep -Seconds 30 try { $result = Get-AzureADDevice -objectid $deviceid If ($Result -eq $true) { write-host "... $name has been successfully deleted from Entra ID" -ForegroundColor "green" } else { Write-Host "... $name has NOT been deleted from Entra ID" -ForegroundColor "red" } } Catch { Write-Host "... $name has been successfully deleted from Entra ID" -ForegroundColor "green" } } write-host "[ Now the machine has been deleted you will need to re-enroll it back into Autopilot before re-building ]" -foregroundcolor "DarkGreen" write-host "[ To do this, re-run ICT-Autopilot and select Option 1 ]" -foregroundcolor "DarkGreen" exit } ## Checking TPM version if ((Get-Tpm).ManufacturerVersionFull20) { $Tpm20 = -not (Get-Tpm).ManufacturerVersionFull20.Contains("not supported") } else { $Tpm20 = $false } $TPMGET = tpmtool getdeviceinformation $pattern = "-TPM Spec Version*" $spectemp = $TPMGET -split "`r?`n" | Select-String -Pattern $pattern $Spec = $spectemp -replace ".*:" $spec = $spec.trim() Write-host "... Checking TPM version" -ForegroundColor "darkcyan" if ($tpm20 -eq "true") { Write-host "... Laptop has" -ForegroundColor "darkcyan" -nonewline; write-host " TPM 2.0 " -ForegroundColor "Green" -nonewline; write-host "you may carry on" -ForegroundColor "darkcyan" } else { Write-host "... This laptop does NOT have TPM 2.0, please upgrade the BIOS and start again" -ForegroundColor "red" Write-host "... Exiting script" -ForegroundColor "red" exit } ## Checking Windows Edition $osedition = (Get-WmiObject -class Win32_OperatingSystem).Caption Write-host "... Checking whether laptop is running Windows Enterprise or Pro" -ForegroundColor "darkcyan" if ($osedition -like '*home*') { Write-host "... This machine is running $osedition, you need to be on Professional or Enterprise" -ForegroundColor "red" Write-host "... Please Upgrade and try again" -ForegroundColor "red" Write-host "... Exiting script" -ForegroundColor "red" exit } else { Write-host "... This machine is running " -ForegroundColor "darkcyan" -nonewline; write-host "$osedition" -ForegroundColor "Green" -nonewline; write-host " which is supported by Autopilot" -ForegroundColor "darkcyan" } ## Checking Windows build is 1803 or higher Write-host "... Checking whether Windows is 1803 or higher" -ForegroundColor "darkcyan" $buildnum = (([Environment]::OSVersion).version).build if ($buildnum -ge "17134") { Write-host "... The Windows build is " -ForegroundColor "darkcyan" -nonewline; write-host "$buildnum" -ForegroundColor "Green" -nonewline; write-host " which is supported by Autopilot" -ForegroundColor "darkcyan" } else { Write-host "... The Windows build is $buildnum which is not supported by Autopilot" -ForegroundColor "red" Write-host "... Please Upgrade Windows to a newer version to continue" -ForegroundColor "red" exit } Write-host "... Getting local Serial number" -ForegroundColor "darkcyan" $serial = Get-WmiObject win32_bios | select serialnumber -ExpandProperty serialnumber $greenCheck = @{ Object = [Char]8730 ForegroundColor = 'Green' } $redCross = @{ Object = [Char]120 ForegroundColor = 'red' } write-host "... Installing Autopilot Powershell Module" -ForegroundColor "darkcyan" Install-Module microsoft.graph.authentication -Force install-module Microsoft.Graph.DeviceManagement.Enrollment -force write-host "... Connecting to Imperial College London Tennancy" -ForegroundColor "darkcyan" write-host "... Prompting for credentials" -ForegroundColor "darkcyan" # connect-msgraph | out-null connect-mggraph -nowelcome connect-msgraph | out-null $deets = Get-MgBetaDeviceManagementWindowsAutopilotDeviceIdentity -Filter "contains(serialNumber,'$serial')" # Check to see if the machine is already in Intune write-host "... Checking to see if the machine is already in Intune, this may take a few seconds" -ForegroundColor "darkcyan" $name = (Get-IntuneManagedDevice -filter ("serialnumber eq '$serial'")).devicename $PotName = "IC-" + $serial if ($name -eq $potname) { write-host "This machine already exists in Intune as $name, you will need to go to the Endpoint console and hit WIPE to rebuild it" -ForegroundColor "yellow" write-host -nonewline "You should stop here and continue in the Intune console" -foregroundcolor "yellow" exit } elseif ($name -like "*DESKTOP-*") { Write-host "This machine is in Intune but has a DESKTOP- style name, this usually means that the machine was pre-provisioned at the factory." -ForegroundColor "yellow" write-host "You should not be running this script on machines that have been pre-provisioned" -ForegroundColor "yellow" write-host "This script is ONLY used to enroll machines into Autopilot. ALl machines bought from HP are already in Autopilot" -ForegroundColor "yellow" exit } elseif ($name -like "*LAPTOP*") { Write-host "This machine is in Intune but has a LAPTOP- style name, this usually means that the machine was pre-provisioned at the factory." -ForegroundColor "yellow" write-host "You should not be running this script on machines that have been pre-provisioned" -ForegroundColor "yellow" write-host "This script is ONLY used to enroll machines into Autopilot. ALl machines bought from HP are already in Autopilot" -ForegroundColor "yellow" exit } elseif ($name -like "*TABLET*") { Write-host "This machine is in Intune but has a TABLET- style name, this usually means that the machine was pre-provisioned at the factory." -ForegroundColor "yellow" write-host "You should not be running this script on machines that have been pre-provisioned" -ForegroundColor "yellow" write-host "This script is ONLY used to enroll machines into Autopilot. ALl machines bought from HP are already in Autopilot" -ForegroundColor "yellow" exit } else { write-host "... This machine is not in Intune, Autopilot enrolment will now continue" -ForegroundColor "darkcyan" } if ($deets.enrollmentState -eq "enrolled") { $intune = Get-IntuneManagedDevice -filter ("serialnumber eq '$serial'") if ($intune -eq $null ) { write-host "... $serial is already enrolled, you may carry on with the Autopilot Build " -ForegroundColor "green" } else { write-host "... $serial is enrolled and has been built by Autopilot before, do NOT pre-provision this machine" -foreground "red" write-host "... Use Autopilot Reset in the Endpoint Manager Console" -foreground "red" } } elseif ($deets.enrollmentstate -eq "notcontacted") { $intune = Get-IntuneManagedDevice -filter ("serialnumber eq '$serial'") if ($intune -eq $null ) { write-host "... $serial is already enrolled, you may carry on with the Autopilot Build " -ForegroundColor "green" } else { write-host "... $serial is enrolled and has been built by Autopilot before, do NOT pre-provision this machine" -foreground "red" write-host "... Use Autopilot Reset in the Endpoint Manager Console" -foreground "red" } } else { write-host "... $serial is NOT enrolled, enrolling now" -ForegroundColor "darkcyan" Get-WindowsAutopilotInfo -Online write-host "... Now wait for the profile to be applied, then you can build the machine" -ForegroundColor "darkcyan" write-host "... Checking the assigned status of $serial every 30 seconds until the profile is assigned" -ForegroundColor "darkcyan" write-host "" $importStart = Get-Date do { start-Sleep 30 $deets = Get-MgBetaDeviceManagementWindowsAutopilotDeviceIdentity -Filter "contains(serialNumber,'$serial')" if ($deets.deploymentProfileAssignmentStatus -eq "notassigned" ) { write-host "... $serial is still unassigned" -ForegroundColor "yellow" } elseif ($deets.deploymentProfileAssignmentStatus -eq "pending" ) { write-host "... $serial is being assigned a profile" -ForegroundColor "yellow" } elseif ($deets.deploymentProfileAssignmentStatus -eq "assignedUnkownSyncState") { write-host "... $serial now has a profile assigned" -ForegroundColor "darkcyan" $importDuration = (Get-Date) - $importStart $importSeconds = [Math]::Ceiling($importDuration.TotalSeconds) write-host "... Elapsed time to complete import of $serial : $importSeconds seconds" -ForegroundColor "darkcyan" write-host "... You can now Autopilot this machine" -ForegroundColor "green" write-host "" write-host "[ We recommend that you wait a couple of minutes before you reboot this machine and run Autopilot ]" -ForegroundColor "DarkGreen" write-host "[ This is to ensure that the assigned profile is fully applied to the machine ]" -ForegroundColor "DarkGreen" write-host " " write-host "... Do you wish to reboot right now? (Y/N) " -foregroundcolor "darkcyan" $response = read-host if ( $response -ne "Y" ) { exit } shutdown /f /r /t 1 } } until ($deets.deploymentProfileAssignmentStatus -eq "assignedUnkownSyncState" ) } # SIG # Begin signature block # MIIRCAYJKoZIhvcNAQcCoIIQ+TCCEPUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUBS9jNL29YcFwlcQsyNu5n/TH # lraggg47MIIG7zCCBNegAwIBAgITIQAAAAQ+jdT+OF0JbAAAAAAABDANBgkqhkiG # 9w0BAQsFADCBzTExMC8GCSqGSIb3DQEJARYiaXQtc2VjdXJpdHktb2ZmaWNlckBp # bXBlcmlhbC5hYy51azELMAkGA1UEBhMCVUsxDzANBgNVBAgTBkxvbmRvbjEPMA0G # A1UEBxMGTG9uZG9uMSAwHgYDVQQKExdJbXBlcmlhbCBDb2xsZWdlIExvbmRvbjFH # MEUGA1UEAxM+SW1wZXJpYWwgQ29sbGVnZSBMb25kb24gUm9vdCBTZWN1cmUgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjAwMjA0MTQ1ODE5WhcNNDEwMjA0 # MTUwODE5WjB+MRIwEAYKCZImiZPyLGQBGRYCdWsxEjAQBgoJkiaJk/IsZAEZFgJh # YzESMBAGCgmSJomT8ixkARkWAmljMUAwPgYDVQQDEzdJbXBlcmlhbCBDb2xsZWdl # IFN1Ym9yZGluYXRlIENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMIICIjANBgkq # hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwWXS9zPICV4jIdQq8gEWILjc77DGVFAX # iQw5jnbpEbp0MRybyO7xhkgvPWjApnFBQVb2MLl38kXDGfFOkk6BxM8rdzbGk7dN # 1+g5P1HMAxBEv7g3xwOMRhruXwmcFYhXO9aK5vm+LfwgB+7cI3Rald0xH88c/j2O # 5oyXwipm8QKTq+uiQgc1hJicGTwpee+MgIKg4ErOGd7u6WworI4Q5ssTRLc4QsTN # 3FsH/YoNcIH8YBOf6zsyyFVAp81wwtnpXbmb12t81xL8ilJCzId621nGmSaIieTG # t5WO3lHb5hDAR6d7j5FGvilkG5NxLqxDcTcAZwzi47J4G17XLonzG2dis5gdbxuC # csJtI15D4yIuelM0QL9tBv1rK9L3a9rNFw68PdKGLFdy45LxNKEPobW99x8akQF9 # BqkuiCQHPwy0J2IT8mGDFrwJOkQafuZH05oD9Ve0DSEmfkrb2ov3RJCtfMeoPXX8 # qqwciLbtqBPG7RdUkadvpa/57arpaaqpxmKbKWmQkkIVb70CIjoMsifZo8xOenvJ # lW0PR1DklgBPYFyMVgkjkFBlfByI+RKl2LGHdhGkjYor5Vm+0BpuvmafhzmKq4hl # t3x9w6ej3PG47hfRs2/x2rle98BXdEErbOYJQDiwC9zLWakbtXRbczJdpNRfcWOQ # VRXfK/ohEAECAwEAAaOCARQwggEQMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQW # BBSEUdMHUDoNmOjy1Qr0hY7LRkokGzAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA # QTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSyoWQR # aDlAlbayM02OogP+NFWLajCBggYDVR0fBHsweTB3oHWgc4ZxaHR0cDovL2ljY2E0 # LmljLmFjLnVrL0NlcnRFbnJvbGwvSW1wZXJpYWwlMjBDb2xsZWdlJTIwTG9uZG9u # JTIwUm9vdCUyMFNlY3VyZSUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAy # MC5jcmwwDQYJKoZIhvcNAQELBQADggIBAJynGpiQjCg0dKkERvQ1cjFGykU5AyFL # su+UShC4yXsGEu07OfkmY2d+75A8p6hXzcZW/KgpWQ39eaeKITi5q5ChdsXHHszW # /JZPFaJk1cV/DwPSKKa2KJDG1TtwYUWrVFZMR+r3ns+If6f5IPJMIEU8MmBncAo0 # KaIIljwS8uRSFBW9XmaGCrxFeRs+n2a+sjf+NUXtriCgJz+8lNGzyP9Ge1/1IU8b # ZJuiV1/DgHSwqMHfVDxYPYY5RDHVnWRlSPN6R+d40Vd+ZxWq1jMxUCuRJPjjCmL3 # j/SuoAtJit5r+6yisR4jobV8wtgeFq7zLGYPz96/3BdPN/HEmmSLyi0AjiRY23jY # cDAlM+cAgNgoMyoHt77PVrkYMM8NI5GSu0PcRT+pkCEyzyGdaVWUZhzN5TmPyvrj # mwQsKuOY3B1Eid5xv+NBZGnJmJQfhiHzdu7J1h+xoLy6ylf0dkoBl1lV9JUSv8bY # bTJ3Ds+FjwH6B/6ns7Qwq89d6WnnQJDwfWDPvOC+7s8jOGaYReijxkNE/8GUK69b # Iw6oyCHjfMiyPMhnIMRZJP6jUPzP5Ka2xFOEWDWivfAolRtJjQbqGLQiITDLzY23 # bKIhdKL4FdGNd8a5z6HIe/r6Zhn4E4RkrJ8JP3dzbcxwLWVxxLk+GD2G0PP+vFJ8 # r24tTZBnA3U8MIIHRDCCBSygAwIBAgITbQAC4ullHJjXjzOpdwAAAALi6TANBgkq # hkiG9w0BAQsFADB+MRIwEAYKCZImiZPyLGQBGRYCdWsxEjAQBgoJkiaJk/IsZAEZ # FgJhYzESMBAGCgmSJomT8ixkARkWAmljMUAwPgYDVQQDEzdJbXBlcmlhbCBDb2xs # ZWdlIFN1Ym9yZGluYXRlIENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4XDTIx # MDgxNzE1Mjc0M1oXDTI2MDgxNjE1Mjc0M1owfDEPMA0GA1UEBxMGTG9uZG9uMSAw # HgYDVQQKExdJbXBlcmlhbCBDb2xsZWdlIExvbmRvbjEaMBgGA1UECxMRSUNUIEVV # QyBDb2RlIFNpZ24xKzApBgkqhkiG9w0BCQEWHGphc29uLmJlbm5ldHRAaW1wZXJp # YWwuYWMudWswggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIxO4kTEjy # 59THp/+s5SzWc/GmI5U+EIiomLUl29lrQb5uKwxg771VbtAxDC7Cp/QMiVPWcZWg # fuiU7ku2awzlYzi9VOMQO1vodpcBX3qHux1L3c2580l0N57qJnxMjHpcsbvnGcoM # It9Etufkv1kLmTWiQOdFG1SRFKpF1hqvqjYHghThPQwz4ZdWn9m7+qWYJSrJ5SDp # 4PredIgfJwcmbn14/wmihuXxAdxWd3gdgGPRiKdH2WeCTlVT9IBTu9gP5FBLhXUl # Gg7lUkqVnJyxzlP6PhjvuVvOsSf+YfPTU/+cPfHBUAhMPw6KWcVCfZ46uvqSgBft # zXvn6s6N8lpNAgMBAAGjggK7MIICtzA8BgkrBgEEAYI3FQcELzAtBiUrBgEEAYI3 # FQiGwpoMgYTsC82RAYTl+DaHmsUBRYHk5RmF75EkAgFkAgEIMBMGA1UdJQQMMAoG # CCsGAQUFBwMDMAsGA1UdDwQEAwIFoDAbBgkrBgEEAYI3FQoEDjAMMAoGCCsGAQUF # BwMDMB0GA1UdDgQWBBQlMfwwz4lk5V87PMknQfO9ttwfHDAfBgNVHSMEGDAWgBSE # UdMHUDoNmOjy1Qr0hY7LRkokGzCB/wYDVR0fBIH3MIH0MIHxoIHuoIHrhoHobGRh # cDovLy9DTj1JbXBlcmlhbCUyMENvbGxlZ2UlMjBTdWJvcmRpbmF0ZSUyMENlcnRp # ZmljYXRlJTIwQXV0aG9yaXR5JTIwLTAwNzQwLENOPWljY2E0LENOPUNEUCxDTj1Q # dWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0 # aW9uLERDPWljLERDPWFjLERDPXVrP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/ # YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDCB9QYIKwYBBQUH # AQEEgegwgeUwgeIGCCsGAQUFBzAChoHVbGRhcDovLy9DTj1JbXBlcmlhbCUyMENv # bGxlZ2UlMjBTdWJvcmRpbmF0ZSUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIw # LTAwNzQwLENOPUFJQSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2 # aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWljLERDPWFjLERDPXVrP2NBQ2VydGlm # aWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0aG9yaXR5MA0G # CSqGSIb3DQEBCwUAA4ICAQCPxZGIOolo569qE7sw2Kuf+wjYWN6XaedFn8ATJeJj # IAZvUHhn8fDJrrdEfAsAEWUKVmh9wCJ8O93KmpoqDLw8gdhyz/I8eXssZkssonG5 # 1n5APZ9TlA2O2CIIGWNKtMFSjm+KUKmDTbGyq9xlwY6S3u376mKYoZJNoXHveyVP # tRdvvAthN+XgFjbWaE5Y/xykOGI+CcMy+veL5/xEOStWRN6lFCuU1Mr3FiPy018o # a9RUNouRvLV46pSBrDvuj0glOUFqjuqClZ/2qY0pCFZHtguV3VProVAJQIo9TjS4 # RcnQQ8oxMFXTU1bT4gWDw4pR6bZS3ozmGt3GFRDRZoI0Jly+ID1CCxEKFYOw1g1z # jM+s/FdKfMDEbLZUVzzEPxCG45TDVI3PTPS/EZ8ySwyGq6qbwsK3HXPGCR1YA6zt # K8Ua7qweTAC4jGIQSWv4RnZkZc/th0rHQEEa8MTKDIi+HrNzfAnXhqwJdgfimAc6 # Bl7BwGKtNRVMBxjoFrX3ruXXRi6FrTDPZ/f/0HXIu6T1KlKlWoFZj0++gROD1zFR # UE9jUW6/Ug3hbGOiDDHf6uNCTrl7eK9BAhlkJQCO1/iJ/JwQz9+pkXD/rkODVssU # c/XQxjRwjcnwWqsbU2hPGbfZuwAseQhgVlx//63swaKYxq6gDGuCySVBwenbvJ8Z # VDGCAjcwggIzAgEBMIGVMH4xEjAQBgoJkiaJk/IsZAEZFgJ1azESMBAGCgmSJomT # 8ixkARkWAmFjMRIwEAYKCZImiZPyLGQBGRYCaWMxQDA+BgNVBAMTN0ltcGVyaWFs # IENvbGxlZ2UgU3Vib3JkaW5hdGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAC # E20AAuLpZRyY148zqXcAAAAC4ukwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwx # CjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGC # NwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFMju75NmuefSrsSx # hEcc3ty4ymxoMA0GCSqGSIb3DQEBAQUABIIBADKaRj/h1aMfJXAJKje2cYlqvyzV # 609QswkcqnBvK1udx1PG1khsInL9ItU1qA72VxR3EbOOvK/ePFi23dLnMhzSsBRt # h8ksgxLgnbIt3IFilJjBUwqX27EGVuL3R8G5ceJwaW2rm38PH0+2Omr+DbZnMfiM # DJHyWYEiQnPIPjSIRrAPdiPntqvUskio0/0ispDfu0XQi4yY903j4qNooUQ0kJHh # ANLFnkWrLQ6Z02Rqlm8cSzVDZpc5XzyfE2nV6rygIl6OZsJ6D9jT2DC+KRm5vg0K # gMEoBmyqiDPcHpsBRxWALVcmSEzhsAN1vh/3020zUwEBrtrzWL+ae50MpWc= # SIG # End signature block |