ict-autopilot.ps1


<#PSScriptInfo
 
.VERSION 2.3.4
 
.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 Machine-checks
{
    ## 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
            }
}

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 -allowclobber -Confirm:$False
        }
        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 -allowclobber -Confirm:$False
            }
            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 -allowclobber -Confirm:$False
            }

                    $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 -allowclobber -Confirm:$False
            }
        }

            # 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" -nowelcome
                    $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

# set the psgallery as trusted


write-host "/---------------------------------------------------------\" -foreground "darkcyan"
write-host "|" -foreground "darkcyan" -nonewline;  write-host " Autopilot Enrollment -- " -foreground "yellow" -nonewline; write-host " 2.3.4 " -foregroundcolor "white" -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 " 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 ""
$serial = Get-WmiObject win32_bios | select serialnumber -ExpandProperty serialnumber
write-host "Serial number - " -foregroundcolor "Darkcyan" -nonewline; write-host "$serial" -foregroundcolor "white"
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 "If the serial number above looks odd, ie. 'System Serial Number', 'To be filled by O.E.M.' or if it's blank" -ForegroundColor "white" -BackgroundColor "Darkcyan"
write-host "then choose Option 7 to build it as a custom machine" -ForegroundColor "white" -BackgroundColor "darkcyan"
write-host " "
write-host "1. " -foreground "green" -nonewline; write-host "Enroll this machine in Autopilot" -foreground "yellow"
write-host "2. " -foreground "green" -nonewline; write-host "Create Enrolment CSV that can be imported via Intune" -foreground "yellow"
write-host "3. " -foreground "green" -nonewline; write-host "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. " -foreground "green" -nonewline; write-host "Display machine Information" -foreground "yellow"
write-host "5. " -foreground "green" -nonewline; write-host "Reboot computer" -foreground "yellow"
write-host "6. " -foreground "green" -nonewline; write-host "(not working right now) Totally delete machine from Autopilot, Intune and Entra ID - " -foreground "yellow" -nonewline; write-host "ICT Engineers Only" -foreground "darkcyan"
write-host " (We recommend you use Option 6 when a machine gives a Red Screen after failing Autopilot Pre-Provision)" -foreground "yellow"
write-host "7. " -foreground "green" -nonewline; write-host "Build as a custom built machine (ie not HP, Dell, Lenovo etc)" -foreground "yellow"
write-host " "
write-host " "

Unregister-PackageSource -Source PSGallery
Register-PackageSource -Name PSGallery -ProviderName PowerShellGet -Trusted | out-null

$input = Read-Host  -Prompt 'Please choose an option (enter a number)'
write-host " "
write-host " "

if ($input -eq '3')
    {
        ## Patching PC
        ##############

        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 -allowclobber -Confirm:$False
        set-executionpolicy remotesigned
        Get-WindowsUpdate -AcceptAll -Install -AutoReboot
        exit
    }

if ($input -eq '4')
    {
        ## Getting Machine info
        #######################

        $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')
    {
        ## Creating local CSV file for enrolment
        ########################################

        Machine-checks
            
        ## 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')
    {
        ## Rebooting machine
        ####################
        #
        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')
    {
        ## Deleting machine from everywhere
        ###################################
                
        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 -allowclobber -Confirm:$False
        install-module Microsoft.Graph.intune -force -allowclobber -Confirm:$False
        Install-Module microsoft.graph.authentication -force -allowclobber -Confirm:$False
        install-module microsoft.graph.beta.devicemanagement.enrollment -force -allowclobber -Confirm:$False
        install-module microsoft.graph.devicemanagement.enrollment -force -allowclobber -Confirm:$False
        install-module azuread -force -allowclobber -Confirm:$False
        connect-mggraph -NoWelcome
        connect-azuread
        connect-msgraph | out-null


        # Delete from intune

        write-host "... Getting Intune machine data"  -ForegroundColor "darkcyan"
        $info = Get-ComputerInfo
        $name = (Get-MgBetaDeviceManagementManagedDevice -Filter "serialnumber eq '$serial'").devicename
        $IntuneID = (Get-MgBetaDeviceManagementManagedDevice -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-MgBetaDeviceManagementManagedDevice -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
    }

if ($input -eq '7')
    {
        ## Enrolling Custom Built machine
        #################################
        ##
        machine-checks

        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 -allowclobber -Confirm:$False
                install-module Microsoft.Graph.DeviceManagement.Enrollment -force -allowclobber -Confirm:$False
                install-module Microsoft.Graph.DeviceManagement -force -allowclobber -Confirm:$False
                install-module Microsoft.Graph.intune -force -allowclobber -Confirm:$False
                write-host "... Connecting to Imperial College London Tennancy"  -ForegroundColor "darkcyan"
                write-host "... Prompting for credentials"  -ForegroundColor "darkcyan"
                
                
                # connect-msgraph | out-null
                connect-mggraph -NoWelcome
                # $enrolled = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -Filter "contains(serialNumber,'$serial')"
                $enrolled = Get-AutopilotDevice -serial $serial
        
        
                $managedid = $enrolled.manageddeviceid
                # 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"
        
        
                if ($enrolled -eq $null)    
                    {
                        write-host "... This machine is not enrolled in Autopilot, enrolment will now continue" -ForegroundColor "darkcyan"    
                    }
        
                else
                    {
                        write-host "... $serial is already enrolled in Autopilot" -ForegroundColor "green"    
                        exit
                    }
                else 
                    {
                        write-host "... $serial is NOT enrolled, enrolling now"  -ForegroundColor "darkcyan"
                        write-host "... This will enrol $serial as a Custom built machine and assign it a custom machine name"  -ForegroundColor "darkcyan"
                        write-host "... The name will be IC-RANDOM, where RANDOM is 5 random alpha-numeric characters"  -ForegroundColor "darkcyan"
                        $importStart = Get-Date
                        Get-WindowsAutopilotInfo -GroupTag CUSTOM -Online -assign
                        write-host ""
                        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 ""
                        write-host ""
                        write-host "--[You can now Autopilot this machine]--" -ForegroundColor "green"
                        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
                    }



    }    



machine-checks

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 -allowclobber -Confirm:$False
        install-module Microsoft.Graph.DeviceManagement.Enrollment -force -allowclobber -Confirm:$False
        install-module Microsoft.Graph.DeviceManagement -force -allowclobber -Confirm:$False
        install-module Microsoft.Graph.intune -force -allowclobber -Confirm:$False
        install-module Microsoft.Graph.Beta.DeviceManagement -force -allowclobber -Confirm:$False
        Install-Module -Name WindowsAutopilotIntuneCommunity -allowclobber
        write-host "... Connecting to Imperial College London Tennancy"  -ForegroundColor "darkcyan"
        write-host "... Prompting for credentials"  -ForegroundColor "darkcyan"
        
        
       
        connect-mggraph -NoWelcome
        # $enrolled = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -Filter "contains(serialNumber,'$serial')"
        $enrolled = Get-AutopilotDevice -serial $serial


        $managedid = $enrolled.manageddeviceid
        # 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"


        if ($enrolled -eq $null)    
            {
                write-host "... This machine is not enrolled in Autopilot, enrolment will now continue" -ForegroundColor "darkcyan"    
            }

        else
            {
                write-host "... $serial is already enrolled in Autopilot" -ForegroundColor "green"    
                exit
            }

        else 
            {
                write-host "... $serial is NOT enrolled, enrolling now"  -ForegroundColor "darkcyan"
                $importStart = Get-Date
                Get-WindowsAutopilotInfo -Online -assign
                write-host ""
                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 ""
                write-host ""
                write-host "-- [You can now Autopilot this machine] --" -ForegroundColor "green"
                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

            }


# 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