Driver.Firmware.Servicing.psm1
#Region '.\Private\Invoke-GetRequest.ps1' 0 function Invoke-GetRequest { <# .SYNOPSIS Performs Get Requests with Pagination. .DESCRIPTION Performs Get Requests with Pagination. Without the logic in this function, all results would not be returned. .NOTES Tested on PowerShell 5 and 7 on Windows. .EXAMPLE Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/me" Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/me" -All .PARAMETER Uri The URI to perform the Get Request on. This is a mandatory parameter. .PARAMETER All This switch will determine if paginated requests will be run. This is an optional parameter. #> [CmdletBinding()] param ( # Parameter help description [Parameter(Mandatory = $true)] [string] $Uri, # This switch will determine if paginated requests will be run [switch] $All ) process { switch ($All) { true { $getRequestParameters = @{ Method = "GET" URI = $Uri } $getRequest = Invoke-MgGraphRequest @getRequestParameters -ErrorAction Stop $requestArray = @() $requestArray += IF ($getRequest.value) { $getRequest.value }else { $getRequest } while ($getRequest.'@odata.nextLink') { $getRequest_NextLink = @{ Method = "GET" URI = $getRequest.'@odata.nextLink' } $getRequest = Invoke-MgGraphRequest @getRequest_NextLink -ErrorAction Stop $requestArray += IF ($getRequest.value) { $getRequest.value }else { $getRequest } } $return = $requestArray } false { $getRequestParameters = @{ Method = "GET" URI = $Uri } $return = (Invoke-MgGraphRequest @getRequestParameters -ErrorAction Stop).value } } } end { return $return } } #EndRegion '.\Private\Invoke-GetRequest.ps1' 62 #Region '.\Public\Add-DriverUpdatePolicyAudienceMember.ps1' 0 function Add-DriverUpdatePolicyAudienceMember { <# .SYNOPSIS Add members to a deployment audience for Windows Updates for Business .DESCRIPTION This function will check if the deployments audiences have the devices as members, and if not they will be added to the audience. .EXAMPLE Add-DriverUpdatePolicyAudienceMember -azureDeviceIDs ("ID1","ID2") -updateAudienceID <AudienceID> .PARAMETER azureDeviceIDs The Azure Device IDs to add to the audience. .PARAMETER updateAudienceID The Update Audience ID to add the members to. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [array] $azureDeviceIDs, # The Update Audience ID [Parameter(Mandatory = $true)] [string] $updateAudienceID ) begin { # Create the param body base $paramBody = @{ addMembers = @( ) } } process { $updateAudienceMembers = Get-DriverUpdatePolicyAudienceMember -policyID $updateAudienceID foreach ($id in $azureDeviceIDs) { IF (-Not($updateAudienceMembers.id -contains $id)) { $memberObject = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.azureADDevice" id = $id } $paramBody.addMembers += $memberObject } } } end { IF ($paramBody.addMembers.Count -ge 1) { Invoke-MgGraphRequest ` -Method POST ` -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences('$updateAudienceID')/updateAudience" ` -Body $paramBody } } } #EndRegion '.\Public\Add-DriverUpdatePolicyAudienceMember.ps1' 53 #Region '.\Public\Get-DriverUpdateDeploymentAudience.ps1' 0 function Get-DriverUpdateDeploymentAudience { <# .SYNOPSIS This function get Update Deployment Audiences. .DESCRIPTION This function get Update Deployment Audiences. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Get-DriverUpdateDeploymentAudience Get-DriverUpdateDeploymentAudience -audienceID <audienceID> .PARAMETER audienceID The audience ID to get the deployment audience for. #> [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string] $audienceID ) process { try { IF ([string]::IsNullOrEmpty($audienceID)) { $DriverUpdateDeploymentAudience = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences" -All } elseif (-Not([string]::IsNullOrEmpty($audienceID))) { $DriverUpdateDeploymentAudience = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences?`$filter=id eq '$audienceID'" } } catch { throw "Unable to get the deployment audiences. $($_.Exception.Message)" } } end { return $DriverUpdateDeploymentAudience } } #EndRegion '.\Public\Get-DriverUpdateDeploymentAudience.ps1' 38 #Region '.\Public\Get-DriverUpdatePolicy.ps1' 0 function Get-DriverUpdatePolicy{ <# .SYNOPSIS This function gets all update policies for Windows Updates for Business for Driver and Firmware Servicing. .DESCRIPTION This function gets all update policies for Windows Updates for Business for Driver and Firmware Servicing. .NOTES This has only been tested for the commercial driver and firmware updates. https://learn.microsoft.com/en-us/graph/api/adminwindowsupdates-list-updatepolicies?view=graph-rest-beta&tabs=http .EXAMPLE Get-DriverUpdatePolicy .PARAMETER policyID The policy ID to get. If not specified, all policies will be returned. #> [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string] $policyID ) process { try { IF([string]::IsNullOrEmpty($policyID)){ $policy = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatePolicies" -All } elseif (-Not([string]::IsNullOrEmpty($AzureADDeviceID))) { $policy = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatePolicies?`$filter=id eq '$policyID'" } } catch { throw "Unable to get the policies. $($_.Exception.Message)" } } end { return $policy } } #EndRegion '.\Public\Get-DriverUpdatePolicy.ps1' 37 #Region '.\Public\Get-DriverUpdatePolicyApplicableContent.ps1' 0 function Get-DriverUpdatePolicyApplicableContent { <# .SYNOPSIS This function will get the deployable content of a deployment audience based on a PolicyID for Windows Updates for Business. .DESCRIPTION This function will get the deployable content of a deployment audience based on a PolicyID for Windows Updates for Business. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Get-DriverUpdatePolicyApplicableContent -policyID <PolicyID> .PARAMETER policyID The policy ID to get the applicable content for. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $policyID ) process { try { $policy = Get-DriverUpdatePolicy -policyID $policyID $applicableConent = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences('$($policy.audience.id)')/applicableContent?`$expand=catalogEntry" -All } catch { throw "Unable to get the applicable content of the deployment audience. $($_.Exception.Message)" } } end { return $applicableConent } } #EndRegion '.\Public\Get-DriverUpdatePolicyApplicableContent.ps1' 33 #Region '.\Public\Get-DriverUpdatePolicyAudienceMember.ps1' 0 function Get-DriverUpdatePolicyAudienceMember { <# .SYNOPSIS This function will get the members of a deployment audience for Windows Updates for Business. .DESCRIPTION This function will get the members of a deployment audience for Windows Updates for Business. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Get-DriverUpdatePolicyAudienceMember -policyID <PolicyID> .PARAMETER policyID The policy ID to get the members for. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $policyID ) process { try { $policy = Get-DriverUpdatePolicy -policyID $policyID $members = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences('$($policy.audience.id)')/members" -All } catch { throw "Unable to get the members of the deployment audience. $($_.Exception.Message)" } } end { return $members } } #EndRegion '.\Public\Get-DriverUpdatePolicyAudienceMember.ps1' 33 #Region '.\Public\Get-UpdatableAsset.ps1' 0 function Get-UpdatableAsset { <# .SYNOPSIS This function get all updateable assets for Windows Updates for Business. .DESCRIPTION This function get all updateable assets for Windows Updates for Business. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Get-UpdatableAsset Get-UpdatableAsset -AzureADDeviceID <AzureADDeviceID> .PARAMETER AzureADDeviceID The Azure AD Device ID to get the updatable asset for. #> [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string] $AzureADDeviceID ) process { try { IF ([string]::IsNullOrEmpty($AzureADDeviceID)) { $updatableAsset = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatableAssets" -All } elseif (-Not([string]::IsNullOrEmpty($AzureADDeviceID))) { $updatableAsset = Invoke-GetRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatableAssets?`$filter=id eq '$AzureADDeviceID'" } } catch { throw "Unable to get the updatable assets. $($_.Exception.Message)" } } end { return $updatableAsset } } #EndRegion '.\Public\Get-UpdatableAsset.ps1' 38 #Region '.\Public\New-DriverUpdateDeploymentAudience.ps1' 0 function New-DriverUpdateDeploymentAudience { <# .SYNOPSIS Creates a WUfBDS Deployment Audience .DESCRIPTION Creates a WUfBDS Deployment Audience for Policy Assignment. .EXAMPLE New-DriverUpdateDeploymentAudience .PARAMETER daAudienceParams The parameters to create the deployment audience. #> [CmdletBinding(SupportsShouldProcess = $true)] param ( $daAudienceParams = @{} ) process { if ($pscmdlet.ShouldProcess( 'Creating a WUfBDS Deployment Audience', 'Warning: Creating a WUfBDS Deployment Audience', 'Question: Are you sure you want to do continue?')) { $daAudience = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences" -Method POST -Body $daAudienceParams } } end { return $daAudience } } #EndRegion '.\Public\New-DriverUpdateDeploymentAudience.ps1' 30 #Region '.\Public\New-DriverUpdatePolicy.ps1' 0 function New-DriverUpdatePolicy { <# .SYNOPSIS This function is to be used to create a Driver Policy for WUfBDS .DESCRIPTION Based on the inputs, will depend on the policy creation type of Manual or Automatic. .EXAMPLE New-DriverUpdatePolicy -deploymentAudienceID $daAudience.id -policyType Automatic -deferralTime PT1D .PARAMETER deploymentAudienceID The Deployment Audience ID. This can be obtained from the Get-DriverUpdateDeploymentAudience function. .PARAMETER policyType The type of policy to create. Manual or Automatic. .PARAMETER deferralTime The deferral time for the policy. This is only required for Automatic policies. #> [CmdletBinding(SupportsShouldProcess=$true)] param ( # The Deployment Audience ID [Parameter(Mandatory = $true)] [string] $deploymentAudienceID, # Manual or Automatic Publishing Policy [Parameter(Mandatory = $true)] [ValidateSet("Manual", "Automatic")] [string] $policyType, # ISO8601 Timeformat for Deferral [Parameter()] [string] $deferralTime = "PT0S" ) begin { #Initialise the base object body. $paramBody = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.updatePolicy" audience = @{ id = $deploymentAudienceID } autoEnrollmentUpdateCategories = @( "driver" ) } } process { switch ($policyType) { Manual { $paramBody.deploymentSettings = @{ schedule = $null monitoring = $null contentApplicability = $null userExperience = $null expedite = $null } } Automatic { $paramBody.deploymentSettings = @{ schedule = $null monitoring = $null contentApplicability = @{ offerWhileRecommendedBy = @( "microsoft" ) safeguard = $null } userExperience = $null expedite = $null } $paramBody.complianceChangeRules = @( @{ "@odata.type" = "#microsoft.graph.windowsUpdates.contentApprovalRule" durationBeforeDeploymentStart = $deferralTime contentFilter = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.driverUpdateFilter" } } ) } } } end { if ($PSCmdlet.ShouldProcess( 'Creating a WUfBDS Driver Update Policy', 'Warning: Creating a WUfBDS Driver Update Policy', 'Question: Are you sure you want to do continue?')) { Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatePolicies"` -Method POST ` -Body $paramBody ` -ContentType 'application/json' } } } #EndRegion '.\Public\New-DriverUpdatePolicy.ps1' 93 #Region '.\Public\Push-EnrollUpdateableAsset.ps1' 0 function Push-EnrollUpdateableAsset { <# .SYNOPSIS This script is to be used to push enrol assets as without it, the delay could be significant. .DESCRIPTION This script is to be used to push enrol assets as without it, the delay could be significant. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Push-EnrollUpdateableAsset -azureDeviceIDs ('ID1','ID2') .PARAMETER azureDeviceIDs The Azure AD Device IDs to enroll as updateable assets. #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true)] [array] $azureDeviceIDs ) begin { # Create the param body base $paramBody = @{ updateCategory = "driver" assets = @( ) } } process { if($PSCmdlet.ShouldProcess("Enroll Assets", "Enroll Assets")) { $updateAudienceMembers = Get-DriverUpdatePolicyAudienceMember -policyID $updateAudienceID foreach ($id in $azureDeviceIDs) { IF (-Not($updateAudienceMembers.id -contains $id)) { $memberObject = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.azureADDevice" id = $id } $paramBody.addMembers += $memberObject } } } $updatableAssets = Get-UpdatableAsset foreach ($id in $azureDeviceIDs) { IF (-Not($updatableAssets | Where-Object { $_.id -match $id }).enrollments.updateCategory -notcontains "driver") { $memberObject = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.azureADDevice" id = $id } $paramBody.assets += $memberObject } } } end { IF ($paramBody.assets.Count -ge 1) { Invoke-MgGraphRequest ` -Method POST ` -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatableAssets/enrollAssets" ` -Body $paramBody } } } #EndRegion '.\Public\Push-EnrollUpdateableAsset.ps1' 61 #Region '.\Public\Remove-DriverUpdatePolicyAudienceMember.ps1' 0 function Remove-DriverUpdatePolicyAudienceMember { <# .SYNOPSIS Remove members from a deployment audience for Windows Updates for Business .DESCRIPTION This function will check if the deployments audiences have the devices as members, and if so they will be removed from the audience. .EXAMPLE Remove-DriverUpdatePolicyAudienceMember -azureDeviceIDs ("ID1","ID2") -updateAudienceID <AudienceID> .PARAMETER azureDeviceIDs The Azure Device IDs to add to the audience. .PARAMETER policyID The Update Policy ID to get the audience from. #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true)] [array] $azureDeviceIDs, # The Update Audience ID [Parameter(Mandatory = $true)] [string] $policyID ) begin { # Create the param body base $paramBody = @{ removeMembers = @( ) } } process { if ($PSCmdlet.ShouldProcess("Remove members from the deployment audience")) { Write-Verbose "Removing members from the deployment audience" } else { return } $updateAudienceID = (Get-DriverUpdatePolicy -policyID $policyID).audience.id $updateAudienceMembers = Get-DriverUpdatePolicyAudienceMember -policyID $policyID foreach ($id in $azureDeviceIDs) { IF ($updateAudienceMembers.id -contains $id) { $memberObject = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.azureADDevice" id = $id } $paramBody.removeMembers += $memberObject } } } end { IF ($paramBody.removeMembers.Count -ge 1) { Invoke-MgGraphRequest ` -Method Post ` -Uri "https://graph.microsoft.com/beta/admin/windows/updates/deploymentAudiences('$updateAudienceID')/updateAudience" ` -Body $paramBody } } } #EndRegion '.\Public\Remove-DriverUpdatePolicyAudienceMember.ps1' 60 #Region '.\Public\Update-DriverUpdatePatchDeferral.ps1' 0 function Update-DriverUpdatePatchDeferral { <# .SYNOPSIS This function is to be used to update the Patch Deferral on Update Policies. .DESCRIPTION This function is to be used to update the Patch Deferral on Update Policies. .NOTES This has only been tested for the commercial driver and firmware updates. .EXAMPLE Update-DriverUpdatePatchDeferral -policyID <id> -deferralTime P1D Explanation of the function or its result. You can include multiple The deferral time must be in the ISO8601 format. .PARAMETER policyID The Update Policy ID. You can get this from the Get-DriverUpdatePolicy function. .PARAMETER deferralTime The deferral time must be in the ISO8601 format. #> [CmdletBinding(SupportsShouldProcess = $true)] param ( # The Update Policy ID [Parameter(Mandatory = $true)] [string] $policyID, # ISO8601 Timeformat for Deferral [Parameter(Mandatory = $true)] [string] $deferralTime ) begin { #The Base Object for the post Body $paramBody = @{ "@odata.type" = "#microsoft.graph.windowsUpdates.updatePolicy" complianceChangeRules = @() } # Create the param body base $complianceChangeRules = (Get-DriverUpdatePolicy -policyID $policyID).complianceChangeRules } process { $paramBody.complianceChangeRules += $complianceChangeRules $paramBody.complianceChangeRules | foreach-object { $_.durationBeforeDeploymentStart = $deferralTime } $deferralTime | Out-Null #Adding in this line to stop the output of the deferral time } end { Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/admin/windows/updates/updatePolicies/$policyID" -Method PATCH -Body $paramBody } } #EndRegion '.\Public\Update-DriverUpdatePatchDeferral.ps1' 48 |