Update_CBDeviceInfoCEEI.ps1
<#PSScriptInfo .VERSION 1.0.0.1 .GUID 222429d7-d4bb-4d2c-a7d6-5b2fda79ad91 .AUTHOR INISAROB .DATE 20/June/2024 .DESCRIPTION Interactive script for CEEI that helps to share details about Autopilot machines with its default tag , deployment profile assignment. .COMPANYNAME .COPYRIGHT Robin .TAGS NA .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .Synopsis Interactive script for CEEI that helps to share details about Autopilot machines with its default tag , deployment profile assignment. #> [CmdletBinding()] param( [Parameter(Mandatory=$False)] [String] $SerialNumber = $null, [Parameter(Mandatory=$False)] [String] $GroupTag = $null, [Parameter(Mandatory=$False)] [Switch] $Status= $True, [Parameter(Mandatory=$False)] [Switch] $Assign= $False, [Parameter(Mandatory=$False)] [String] $csv = $null ) if(!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { Write-Host " Please run script with Administrator rights , Exiting .. " -ForegroundColor Red Exit 1 } $module = Import-Module Microsoft.Graph.Intune -PassThru -ErrorAction Ignore if (-not $module) { Write-Host "Installing module WindowsAutopilotIntune" Install-Module -Name Microsoft.Graph.Intune -Force } Import-Module Microsoft.Graph.Intune -Scope Global try { Update-msgraphenvironment -appid 42a1e9c8-d659-4946-a5b0-e6ad57bdd635 $Connectstatus = Connect-MSGraph -ForceInteractive } catch { Write-Host "Authentication was not successful, Exitng" -ForegroundColor Red exit 1 } # Declaring Variable $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" function Get-CurrentDateTime { return (Get-Date -format "dd-MM-yyyy HH:mm:ss") } Function Get-importedWindowsAutopilotDeviceIdentities ($SerialNumber) { Write-Verbose " $(get-date) Function get-importedWindowsAutopilotDeviceIdentities is called " $ImportStatus = $null $DeviceStatus = $null #Verify that the device as been uploaded, if not try again up to 5 times before throwing an error For ($i = 1; $i -lt 5; $i++) { Write-Verbose "Verifying Status of Autopilot Import" If ($i -ge 5) { Write-Verbose "Autopilot Import Error" Exit 1 } $encoded = [uri]::EscapeDataString($SerialNumber) $uri = "https://graph.microsoft.com/beta/deviceManagement/importedWindowsAutopilotDeviceIdentities?`$filter=contains(serialNumber,'$encoded')" $GetImportedIdentity = Invoke-MSGraphRequest -Url $uri -HttpMethod GET $CurrentImport = $GetImportedIdentity.value | Where-Object { $_.Serialnumber -like $SerialNumber } If ($CurrentImport.State.deviceImportStatus -eq "complete") { Write-Verbose "Autopilot Import Job Status complete"; $ImportStatus = 1 } $uri = "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities?`$filter=contains(serialNumber,'$encoded')" $GetDeviceIdentity = Invoke-MSGraphRequest -Url $uri -HttpMethod GET #$GetDeviceIdentity.value If ($GetDeviceIdentity.value | Where-Object { $_.Serialnumber -like $SerialNumber }) { Write-Verbose "Autopilot Device Found"; $DeviceStatus = 1 } If (($DeviceStatus -eq 1) -and ($ImportStatus -eq 1)) { Start-Sleep -Seconds 20 Write-host "Autopilot Import Completed Successfully" -ForegroundColor Green return 0 } Start-Sleep -Seconds 120 } } Function Get-AutopilotDeviceId ($SerialNumber) { Write-Verbose " $(get-date) Function get-autopilotdeviceid is called " $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" $encoded = [uri]::EscapeDataString($SerialNumber) $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$filter=contains(serialNumber,'$encoded')" $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $AzureDeviceId = $response.value.id if ($AzureDeviceId -eq $null) { Write-Verbose " $(get-date) Device Hash is not uploaded " return $null } else { Write-Verbose " $(get-date) AzureDeviceId: $($AzureDeviceId) " return $AzureDeviceId } } Function Check-CurrentDeviceStatus($SerialNumber) { Write-Verbose " $(get-date) Function Check-CurrentDeviceStatus is called " $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" $encoded = [uri]::EscapeDataString($SerialNumber) $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$filter=contains(serialNumber,'$encoded')" $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $AzureDeviceId = $response.value.id write-verbose "uri : $uri ; response : $response" if ($AzureDeviceId -eq $null) { Write-Host " $(get-date) Device Hash is not uploaded for serial number $SerialNumber" -ForegroundColor red return $null } else { Write-Host " $(get-date) Device Serial number : $SerialNumber" -ForegroundColor Green Write-host " $(get-date) Device Hash is uploaded and Azure id of device : $AzureDeviceId " -ForegroundColor Green $DeviceGroupTagId = $response.value.groupTag if ($DeviceGroupTagId -ne $null) { Write-Host " $(get-date) Current Device Group Tag : $DeviceGroupTagId " -ForegroundColor Green $uri="https://graph.microsoft.com/$graphApiVersion/$($Resource)/$AzureDeviceId"+ "?`$expand=deploymentProfile" try { $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $DeviceDeploymentProfile= $response.deploymentProfileAssignmentStatus $CurrentDPStatus= $response.deploymentProfileAssignmentStatus $CurrentDPRemediationState = $response.remediationState $CurrentDPName =$($response.deploymentProfile.displayName) if($CurrentDPStatus -eq "failed") { Write-Host " *** Issue assigning the profile ***" -ForegroundColor red Write-Host " *** Current Status of Assignment : Fail" -ForegroundColor red Write-host " *** Additional Details : $($response.deploymentProfileAssignmentDetailedStatus) " -ForegroundColor red Write-host " Kindly contact SCCM team for remediation" -ForegroundColor Red exit 1 } if (( $CurrentDPRemediationState -eq "automaticRemediationRequired") -or ($CurrentDPRemediationState -eq "automaticRemediationRequired")) { Write-host " There is change in the hardware , you need to re upload the hardware hash" -ForegroundColor Red Write-host " Kindly contact SCCM team for remediation" -ForegroundColor Red exit 1 } if (($DeviceDeploymentProfile -ne $null) -or ($DeviceDeploymentProfile -ne "unknown")) { $DeviceDeploymentProfileName =$($response.deploymentProfile.displayName) Write-Host " $(get-date) Current Assigned Deployment Profile `t`t: $($DeviceDeploymentProfileName) " -ForegroundColor Green return 0 } else { Write-Host " $(get-date) No Deployment Profile is assigned." -ForegroundColor Red } } catch { Write-Host " $(get-date) Unable to find details for device , exiting" -ForegroundColor Red } } else { Write-Host " $(get-date) Device Group Tag is not set" -BackgroundColor Red } return 1 } } Function Upload-AutopilotDeviceHash($SerialNumber) { Write-host " $(get-date) Function Upload-AutopilotDeviceHash is called " # Defining Variables $graphApiVersion = "beta" $Resource = "deviceManagement/importedWindowsAutopilotDeviceIdentities" Write-Host "Upload-AutopilotDeviceHash: Gathering device hash data from local machine" $DeviceHashData = (Get-WmiObject -Namespace "root/cimv2/mdm/dmmap" -Class "MDM_DevDetail_Ext01" -Filter "InstanceID='Ext' AND ParentID='./DevDetail'").DeviceHardwareData $ProductKey = (Get-WmiObject -Class "SoftwareLicensingService").OA3xOriginalProductKey #if($SerialNumber) #{ # Write-Host " $(get-date) SerialNumber : $SerialNumber is supplied to hash upload" -ForegroundColor Green #} #else #{ # Write-Host " $(get-date) SerialNumber could not be fetched , EXiting " -ForegroundColor Red # break #} if($DeviceHashData) { Write-host " $(get-date) Device Hash Data is supplied to hash upload" -ForegroundColor Green } else { Write-host " $(get-date) Device Hash Data could not be fetched , Exiting " -ForegroundColor Red break } if ($GroupTag -ne $null) { $GroupTagH = $GroupTag } else { $GroupTagH = $null } Write-host " $(get-date) Group Tag : `"$GroupTagH`" : is supplied for hash upload" -ForegroundColor Green if(-not ($ProductKey)) { $ProductKey = $null } Write-host " $(get-date) $ProductKey : `"$ProductKey`" : is supplied for hash upload" -ForegroundColor Green $uri = $null $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" $json = @" { "@odata.type": "#microsoft.graph.importedWindowsAutopilotDeviceIdentity", "groupTag": "$GroupTagH", "serialNumber": "$SerialNumber", "productKey": "$ProductKey", "hardwareIdentifier": "$DeviceHashData", "assignedUserPrincipalName": "", "state": { "@odata.type": "microsoft.graph.importedWindowsAutopilotDeviceIdentityState", "deviceImportStatus": "pending", "deviceRegistrationId": "", "deviceErrorCode": 0, "deviceErrorName": "" } } "@ Write-Verbose " $(get-date) Upload-AutopilotDeviceHash : POST : $uri`n$json" try { Invoke-MSGraphRequest -Url $uri -HttpMethod Post -Content $json sleep -Seconds 60 } catch { write-host " $(get-date) Unable to upload hash of device , exiting" break } } Function Find-Grouptag ($SerialNumber) { Write-verbose " $(get-date) Function Find-Grouptag is called " $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" $encoded = [uri]::EscapeDataString($SerialNumber) $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$filter=contains(serialNumber,'$encoded')" $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $CurrentDeviceId = $response.value.id if ($CurrentDeviceId -eq $null) { Write-Host " $(get-date) Device Hash is not uploaded " -ForegroundColor red return $null } else { Write-verbose " $(get-date) Device Hash is uploaded " Write-verbose " $(get-date) Device Hash is uploaded and Azure id of device : $CurrentDeviceId " $CurrentDeviceGroupTagId = $response.value.groupTag if ($CurrentDeviceGroupTagId -ne $null) { return $CurrentDeviceGroupTagId } else { return $null } } } Function Update-Grouptag ($SerialNumber) { Write-verbose " $(get-date) Update-Grouptag is called " $CurrentDeviceId = Get-AutopilotDeviceId ($SerialNumber) if($CurrentDeviceId -eq $null) { Write-Host " $(get-date) Unable to fetch device id , exiting" -ForegroundColor Red } else { Write-Host " $(get-date) Device with id : $CurrentDeviceId is being updated with Group tag $Grouptag " -ForegroundColor Green } # Defining Variables $uri = $null $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource/$CurrentDeviceId/UpdateDeviceProperties" $json = "{" + " groupTag: `"$GroupTag`"" + " }" Write-verbose " $(get-date) Update-AutopilotDeviceTag : POST : $uri`n$json" try { Invoke-MSGraphRequest -Url $uri -HttpMethod POST -Content $json } catch { Write-verbose " $(get-date) Unable to update Group tag with POST method" -ForegroundColor Red try { Invoke-MSGraphRequest -Url $uri -HttpMethod PATCH -Content $json } catch { Write-verbose " $(get-date) Unable to update Group tag with PATCH method" -ForegroundColor Red Write-Host " $(get-date) Unable to update Group tag for device" -ForegroundColor Red break } } } Function Check-DeviceAssignment ($SerialNumber) { Write-Verbose " $(get-date) Function Check-DeviceAssignment is called with `"$SerialNumber`" " #check if tag is correctly assigned. $CountryName = Validate-GroupTag if ($CountryName) { Write-Verbose " Device will have `"$CountryName`" Deployment Profile" } else { Write-host " $(get-date) Group Tag is invalid , exiting " exit 1 } $CurrentDeviceId = Get-AutopilotDeviceId ($SerialNumber) $graphApiVersion = "beta" $Resource = "deviceManagement/windowsAutopilotDeviceIdentities" $uri="https://graph.microsoft.com/$graphApiVersion/$($Resource)/$CurrentDeviceId"+ "?`$expand=deploymentProfile" try { $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $CurrentDPStatus= $response.deploymentProfileAssignmentStatus $CurrentDPRemediationState = $response.remediationState $CurrentDPName =$($response.deploymentProfile.displayName) if($CurrentDPStatus -eq "failed") { Write-Host " *** Issue assigning the profile ***" -ForegroundColor red Write-Host " *** Current Status of Assignment : Fail" -ForegroundColor red Write-host " *** Additional Details : $($response.deploymentProfileAssignmentDetailedStatus) " -ForegroundColor red Write-host " Kindly contact SCCM team for remediation" -ForegroundColor Red exit 1 } if (( $CurrentDPRemediationState -eq "automaticRemediationRequired") -or ($CurrentDPRemediationState -eq "automaticRemediationRequired")) { Write-host " There is change in the hardware , you need to re upload the hardware hash" -ForegroundColor Red Write-host " Kindly contact SCCM team for remediation" -ForegroundColor Red exit 1 } write-verbose "uri: $uri , $CurrentDPStatus,$CurrentDPName" if ($CurrentDPName -notlike "$CountryName*") { Write-Host " $(get-date) Assigning correct Deploymnet Profile to device " -ForegroundColor Yellow [system.int32]$ElapsedTimeDuration = 1 Write-Host " *** This process should take less than 20 minutes for assigning correct Deployment Profile ***" -ForegroundColor red while ($CurrentDPName -notlike "$CountryName*") { $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $CurrentDPStatus= $response.deploymentProfileAssignmentStatus $CurrentDPName =$response.deploymentProfile.displayName if($CurrentDPStatus -eq "failed") { Write-Host " *** Issue assigning the profile ***" -ForegroundColor red Write-Host " *** Current Status of Assignment : Fail" -ForegroundColor red Write-host " *** Additional Details : $($response.deploymentProfileAssignmentDetailedStatus) " -ForegroundColor red exit 1 } write-verbose "uri: $uri , $CurrentDPStatus,$CurrentDPName" Write-Host " $(get-date) Awaiting for correct Deployment Profile Assignment for Device ( Retry in 1 min) Total Elapsed Time - $ElapsedTimeDuration minute(s)." -ForegroundColor Yellow Write-verbose " $(get-date) CurrentDeviceStatus : Assigned Deployment Profile `t`t: ($CurrentDPStatus) $($CurrentDPName) Please wait!! " [system.int32]$ElapsedTimeDuration = [system.int32]$ElapsedTimeDuration + [system.int32]"1" #added on 202205 if($ElapsedTimeDuration -gt "20") { Write-Host " *** There seems to be issue with assigning correct profile , Please get in touch with your Country SPOC *** " -ForegroundColor Red exit 1 } sleep 60 } Write-Host " $(get-date) Correct Deployment Profile is assigned `t`t: $($CurrentDPName) !! " -ForegroundColor Green Write-host " $(get-date) CurrentDeviceStatus : Correct Deployment Profile is assigned `t`t: $($CurrentDPName) !! " } else { Write-Host " $(get-date) Correct Deployment Profile is already assigned `t`t: $($CurrentDPName) !! " -ForegroundColor Green Write-host " $(get-date) Already Correct Deployment Profile is Assigned`t`t: $($CurrentDPName)!! " } $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $CurrentDPStatus= $response.deploymentProfileAssignmentStatus if ($CurrentDPStatus -like "assigned*") { Write-Verbose " $(get-date) Deployment Profile Status `t`t: ($CurrentDPStatus) !! " } else { Write-Verbose " $(get-date) Deployment Profile Status `t`t: ($CurrentDPStatus) !! " } } catch { Write-Host " $(get-date) Check-DeviceAssignment : Unable to find details for device , exiting" -ForegroundColor Red } } Function Validate-GroupTag() { Write-Verbose " $(get-date) Function FindCountryCode is called with `"$SerialNumber`" parameter " if ($GroupTag -like "SH*" -or $GroupTag -like "LD*" -or $GroupTag -like "KK*") { if($GroupTag.Length -ne 4) { $CountryName = $null } else { $GroupTag1 = $GroupTag.Substring($GroupTag.get_Length()-2) } } else { $GroupTag1 =$GroupTag } switch ($GroupTag1) { AZ { $CountryName = "Azerbaijan" } BA { $CountryName = "Bosnia" } BG { $CountryName = "Bulgaria" } BY { $CountryName = "Belarus" } CA { $CountryName = "Canada" } CH { $CountryName = "Switzerland" } CN { $CountryName = "China" } DE { $CountryName = "Germany" } DK { $CountryName = "Denmark" } EE { $CountryName = "Estonia" } FI { $CountryName = "Finland" } FR { $CountryName = "France" } GR { $CountryName = "Greece" } HK { $CountryName = "HongKong" } HR { $CountryName = "Croatia" } HU { $CountryName = "Hungary" } IN { $CountryName = "India" } IT { $CountryName = "Italy" } KH { $CountryName = "Cambodia" } KZ { $CountryName = "Kazakhstan" } LA { $CountryName = "Laos" } LT { $CountryName = "Lithuania" } LV { $CountryName = "Latvia" } ME { $CountryName = "Montenegro" } MM { $CountryName = "Myanmar" } MY { $CountryName = "Malaysia" } NO { $CountryName = "Norway" } NP { $CountryName = "Nepal" } PL { $CountryName = "Poland" } RS { $CountryName = "Serbia" } SE { $CountryName = "Sweden" } SG { $CountryName = "Singapore" } TR { $CountryName = "Turkey" } TW { $CountryName = "Taiwan" } UA { $CountryName = "Ukraine" } UK { $CountryName = "UnitedKingdom" } VN { $CountryName = "Vietnam" } default {$CountryName = $null} } Write-Verbose " $(get-date) CountryName is : `"$CountryName`"" return $CountryName } #Main Section if($SerialNumber) { Write-Host " $(get-date) Serial number of device to be Queried `t: $SerialNumber" -ForegroundColor Yellow } else { Write-Verbose " $(get-date) No Serial was specified " $SerialNumber = (Get-WmiObject -Class win32_bios).serialnumber Write-Verbose " $(get-date) Serial number of current device `t`t`t: $SerialNumber" } if($GroupTag) { $ValidateGroupTag = Validate-GroupTag if ($ValidateGroupTag -eq $null) { Write-Host " Invalid GroupTag was supplied" -ForegroundColor Red exit 1 } else { Write-verbose " Validate Group tag was supplied and profile to be assigned : $ValidateGroupTag" } } #Get current status of the device based on serialnumber If($Status) { Write-verbose " $(get-date) Status Check is True " $CheckCurrentDeviceStatus = Check-CurrentDeviceStatus($SerialNumber) } else { Write-verbose " $(get-date) Status Check is false " } #Find if we hardware hash for the device. $GetAutopilotDeviceId = Get-AutopilotDeviceId ($SerialNumber) if($GetAutopilotDeviceId -eq $null) { Write-verbose " $(get-date) Hardware Hash is missing for Device with $SerialNumber" # if current device fetch the hardware and update else exit $CurrentSerialNumber = (Get-WmiObject -Class win32_bios).serialnumber if($CurrentSerialNumber -eq $SerialNumber) { Write-Host " $(get-date) Updating Hardware hash for existing device " $UploadAutopilotDevice = Upload-AutopilotDeviceHash ($SerialNumber) Write-Verbose " $(get-date) Return Status of UploadAutopilotDevice : $UploadAutopilotDevice " Write-Verbose " $(get-date) Validating if Get-importedWindowsAutopilotDeviceIdentities was successful" $statusimportedWindowsAutopilotDeviceIdentities = Get-importedWindowsAutopilotDeviceIdentities ($SerialNumber) Write-Verbose " $(get-date) Return Status of get-importedWindowsAutopilotDeviceIdentities : $statusimportedWindowsAutopilotDeviceIdentities " } else { Write-Host " $(get-date) Unable to update Hardware hash for the device , Exiting " -ForegroundColor Red } } else { Write-Verbose " $(get-date) Hardware Hash is available for Device with $SerialNumber" } if($GroupTag) { Write-Verbose " $(get-date) Group Tag to be updated as `t: $GroupTag" } else { Write-Verbose " $(get-date) No Group Tag was specified " } if($GroupTag) { Write-Verbose " Fetching Current group tag for the machine with serial number $SerialNumber " $GroupTagFindFunction = Find-Grouptag ($SerialNumber) Write-Verbose " $(get-date) GroupTagFunction value is : $GroupTagFindFunction " if ($GroupTagFindFunction -eq $null) { Write-Verbose " $(get-date) No GroupTag is assigned to device with serial number $SerialNumber " } else { Write-Verbose " $(get-date) Current GroupTag for device is : `"$GroupTagFindFunction`" " if ($GroupTag -eq $GroupTagFindFunction) { Write-Verbose " $(get-date) No change to GroupTag is needed as they are same `"$GroupTag`" : `"$GroupTagFindFunction`" " } else { Write-Verbose " $(get-date) GroupTag for device are not same `"$GroupTag`" : `"$GroupTagFindFunction`" , calling update function" #$GroupTagUpdateFunction = Update-GroupTag ($SerialNumber) } $GroupTagUpdateFunction = Update-GroupTag ($SerialNumber) } } else { Write-Verbose " Nothing to be done on Group tag" } if($Assign) { if ($GroupTag) { Write-Host " $(get-date) Checking current status of the device : " -ForegroundColor Green Check-DeviceAssignment($SerialNumber) } else { Write-Verbose " $(get-date) Assign is added in command but group tag is missing" } } else { Write-Verbose " $(get-date) Assign is not added in command line so Skipping display" } |