MSCommerceFixed.psm1
#Set TLS [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Add-Type "$PSScriptRoot\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" Add-Type "$PSScriptRoot\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" ################################ # Start: Internal use functions ################################ function Get-AccessTokenFromSessionData() { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [System.Management.Automation.SessionState] $SessionState ) $token = Get-MSCommerceConnectionInfo -SessionState $SessionState $token } function Get-MSCommerceConnectionInfo { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [System.Management.Automation.SessionState] $SessionState ) if ($null -eq $sessionState.PSVariable) { throw "unable to access SessionState. PSVariable, Please call Connect-MSCommerce before calling any other Powershell CmdLet for the MSCommerce Module" } $token = $sessionState.PSVariable.GetValue("token"); if ($null -eq $token) { throw "You must call the Connect-MSCommerce cmdlet before calling any other cmdlets" } return $token } function HandleError() { param( [Parameter(Mandatory = $true)] $ErrorContext, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $CustomErrorMessage ) $errorMessage = $ErrorContext.Exception.Message $errorDetails = $ErrorContext.ErrorDetails.Message if ($_.Exception.Response.StatusCode -eq 401) { Write-Error "Your credentials have expired. Please, call Connect-MSCommerce again to regain access to MSCommerce Module." return } write-error "$CustomErrorMessage, ErrorMessage - $errorMessage ErrorDetails - $errorDetails" } ################################ # End: Internal use functions ################################ ################################ # Start: Exported functions ################################ <# .SYNOPSIS Method to connect to MSCommerce with the credentials specified #> function Connect-MSCommerce() { [CmdletBinding()] param( [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) $ClientID = "3d5cffa9-04da-4657-8cab-c7f074657cad" [Uri]$RedirectUri = [uri] "http://localhost/m365/commerce" [string]$Resource = "aeb86249-8ea3-49e2-900b-54cc8e308f85" IF (($Credential.UserName) -or ($Credential.Password)) { $AuthorityUrl = "https://login.windows.net/common" $UserPasswordCredential = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential($Credential.UserName, $Credential.Password) $AuthenticationContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext($AuthorityUrl) $Token = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($AuthenticationContext, $Resource, $ClientID, $UserPasswordCredential).Result } ELSE { $authorityUrl = "https://login.windows.net/common" $authCtx = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" $authorityUrl $platformParams = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" ([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always) $token = $authCtx.AcquireTokenAsync($Resource, $ClientId, $RedirectUri, $platformParams).Result } if ($null -eq $token) { Write-Error "Unable to establish connection" return } $sessionState = $PSCmdlet.SessionState $sessionState.PSVariable.Set("token", $token) Write-Output "Connection established successfully" } <# .SYNOPSIS Method to retrieve configurable policies #> function Get-MSCommercePolicies() { [CmdletBinding()] param() $token = Get-AccessTokenFromSessionData -SessionState $PSCmdlet.SessionState $correlationId = New-Guid $baseUri = "https://licensing.m365.microsoft.com" $restPath = "$baseUri/v1.0/policies" try { $response = Invoke-RestMethod ` -Method GET ` -Uri $restPath ` -Headers @{ "x-ms-correlation-id" = $correlationId "Authorization" = "Bearer $($token.AccessToken)" } foreach ($policy in $response.items) { New-Object PSObject -Property @{ PolicyId = $policy.id Description = $policy.description DefaultValue = $policy.defaultValue } } } catch { HandleError -ErrorContext $_ -CustomErrorMessage "Failed to retrieve policies" } } <# .SYNOPSIS Method to retrieve a description of the specified policy #> function Get-MSCommercePolicy() { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $PolicyId ) $token = Get-AccessTokenFromSessionData -SessionState $PSCmdlet.SessionState $correlationId = New-Guid $baseUri = "https://licensing.m365.microsoft.com" $restPath = "$baseUri/v1.0/policies/$PolicyId" try { $response = Invoke-RestMethod ` -Method GET ` -Uri $restPath ` -Headers @{ "x-ms-correlation-id" = $correlationId "Authorization" = "Bearer $($token.AccessToken)" } New-Object PSObject -Property @{ PolicyId = $response.id Description = $response.description DefaultValue = $response.defaultValue } } catch { HandleError -ErrorContext $_ -CustomErrorMessage "Failed to retrieve policy with PolicyId '$PolicyId'" } } <# .SYNOPSIS Method to retrieve applicable products for the specified policy and their current settings #> function Get-MSCommerceProductPolicies() { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $PolicyId ) $token = Get-AccessTokenFromSessionData -SessionState $PSCmdlet.SessionState $correlationId = New-Guid $baseUri = "https://licensing.m365.microsoft.com" $restPath = "$baseUri/v1.0/policies/$PolicyId/products" try { $response = Invoke-RestMethod ` -Method GET ` -Uri $restPath ` -Headers @{ "x-ms-correlation-id" = $correlationId "Authorization" = "Bearer $($token.AccessToken)" } foreach ($product in $response.items) { New-Object PSObject -Property @{ PolicyId = $product.policyId ProductName = $product.productName ProductId = $product.productId PolicyValue = $product.policyValue } } } catch { HandleError -ErrorContext $_ -CustomErrorMessage "Failed to retrieve product policy with PolicyId '$PolicyId'" } } <# .SYNOPSIS Method to retrieve the current setting for the policy for the specified product #> function Get-MSCommerceProductPolicy() { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $PolicyId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ProductId ) $token = Get-AccessTokenFromSessionData -SessionState $PSCmdlet.SessionState $correlationId = New-Guid $baseUri = "https://licensing.m365.microsoft.com" $restPath = "$baseUri/v1.0/policies/$PolicyId/products/$ProductId" try { $response = Invoke-RestMethod ` -Method GET ` -Uri $restPath ` -Headers @{ "x-ms-correlation-id" = $correlationId "Authorization" = "Bearer $($token.AccessToken)" } New-Object PSObject -Property @{ PolicyId = $response.policyId ProductName = $response.productName ProductId = $response.productId PolicyValue = $response.policyValue } } catch { HandleError -ErrorContext $_ -CustomErrorMessage "Failed to retrieve product policy with PolicyId '$PolicyId' ProductId '$ProductId'" } } <# .SYNOPSIS Method to modify the current setting for the policy for the specified product #> function Update-MSCommerceProductPolicy() { [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $PolicyId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ProductId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Enabled ) if ("True" -ne $Enabled -and "False" -ne $Enabled) { Write-Error "Value of `$Enabled must be one of the following: `$True, `$true, `$False, `$false" return } $token = Get-AccessTokenFromSessionData -SessionState $PSCmdlet.SessionState $correlationId = New-Guid $baseUri = "https://licensing.m365.microsoft.com" $restPath = "$baseUri/v1.0/policies/$PolicyId/products/$ProductId" $enabledStr = if ("True" -eq $Enabled -or "true" -eq $Enabled) {"Enabled"} else {"Disabled"} $body = @{ policyValue = $enabledStr } if ($False -eq $PSCmdlet.ShouldProcess("ShouldProcess?")) { Write-Output "Updating product policy aborted" return } try { $response = Invoke-RestMethod ` -Method PUT ` -Uri $restPath ` -Body ($body | ConvertTo-Json)` -ContentType 'application/json' ` -Headers @{ "x-ms-correlation-id" = $correlationId "Authorization" = "Bearer $($token.AccessToken)" } write-output "Update policy product success" New-Object PSObject -Property @{ PolicyId = $response.policyId ProductName = $response.productName ProductId = $response.productId PolicyValue = $response.policyValue } } catch { HandleError -ErrorContext $_ -CustomErrorMessage "Failed to update product policy" } } ################################ # End: Exported functions ################################ Write-Output "MSCommerce module loaded" # SIG # Begin signature block # MIIN+wYJKoZIhvcNAQcCoIIN7DCCDegCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUkVh5zuVgfc2Erpc9dtlRd35R # PEWgggsxMIIFSTCCBDGgAwIBAgIRAPMKxE4HZQs+EipTj3vsWEUwDQYJKoZIhvcN # AQELBQAwfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3Rl # cjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQx # IzAhBgNVBAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5nIENBMB4XDTE4MTExNjAw # MDAwMFoXDTIyMTExNjIzNTk1OVowgY4xCzAJBgNVBAYTAk5PMQ0wCwYDVQQRDAQ2 # NDU2MRgwFgYDVQQIDA9Nb3JlIG9nIFJvbXNkYWwxDzANBgNVBAcMBlNrYWFsYTEX # MBUGA1UECQwOS3Zlcm5odXNsaWEgMTgxFTATBgNVBAoMDExhcnMgU3ZpbmdlbjEV # MBMGA1UEAwwMTGFycyBTdmluZ2VuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB # CgKCAQEA3lYNFOUtf0eMeUVVQlCLQTVFJLW5H/U54jYPdAJYtADo/FiZlDtvqcnr # XfFXg7Y1d6yYItV+QsW3eaZGRRbqe7LNpYD7xqxfD1fLWXXXVGr3Bohr0tt+JZ6i # u9+VjBKoypbk81pclZbp1BeXD1LYEfBE0g8avFAfiwT7JYg8qYgCQaDikq69Xijr # qw8hug7fJ1aEzUG+g2o9hjZcaDMmAa8ohVYCmkk0tyybizdUA2P2iiOzcYGTwLih # VuvF7A1sNZ/jZ4ffHlhqLT68oP3dWwIzmkPxSV7vKE3yMITLEQmSP7/uJvp5qg0d # CLv2mz20fMUN2ad2i5QgJ+wnJ/FjuQIDAQABo4IBsDCCAawwHwYDVR0jBBgwFoAU # KZFg/4pN+uv5pmq4z/nmS71JzhIwHQYDVR0OBBYEFKx5HPnt0GiU4dXHDSGe7tCj # 0u5xMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG # AQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBGBgNVHSAEPzA9MDsGDCsGAQQBsjEB # AgEDAjArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8ubmV0L0NQ # UzBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01P # RE9SU0FDb2RlU2lnbmluZ0NBLmNybDB0BggrBgEFBQcBAQRoMGYwPgYIKwYBBQUH # MAKGMmh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNvZGVTaWduaW5n # Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wIQYD # VR0RBBowGIEWbGFycy5zdmluZ2VuQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOC # AQEAVVafexhPkBmVX66iUEO9cka2KDhnoa67LS3+vS0+Q+jjny9bVTYvZXbSaDmk # WgQKZZk3iK0AMum3eCg+Hkm4bkfar2zBUeABX45IdAV1I698GHZkmsIWAjematn7 # 5qQnX3t0Xjz6RBkvfTdItY6sFzZUAkDUGtiy3BCfANgkQKhqTvRljK6S653tynqt # yVvb65E+K7rbe6S00L6ichAUCYM2EUV9PpvZMViUrz74pAlOl2oopOBc8SGPWC+U # Ja/IdQocXch1+ePnkktgZBDqVMkoP846Bh0CrPOxBPAAgMy/407jXXfjqJL8TZdD # MvT9GeBtv8Spl9aQSl+lYRzA+zCCBeAwggPIoAMCAQICEC58h8wOk0pS/pT9HLfN # NK8wDQYJKoZIhvcNAQEMBQAwgYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVh # dGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9E # TyBDQSBMaW1pdGVkMSswKQYDVQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24g # QXV0aG9yaXR5MB4XDTEzMDUwOTAwMDAwMFoXDTI4MDUwODIzNTk1OVowfTELMAkG # A1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMH # U2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxIzAhBgNVBAMTGkNP # TU9ETyBSU0EgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A # MIIBCgKCAQEAppiQY3eRNH+K0d3pZzER68we/TEds7liVz+TvFvjnx4kMhEna7xR # kafPnp4ls1+BqBgPHR4gMA77YXuGCbPj/aJonRwsnb9y4+R1oOU1I47Jiu4aDGTH # 2EKhe7VSA0s6sI4jS0tj4CKUN3vVeZAKFBhRLOb+wRLwHD9hYQqMotz2wzCqzSgY # dUjBeVoIzbuMVYz31HaQOjNGUHOYXPSFSmsPgN1e1r39qS/AJfX5eNeNXxDCRFU8 # kDwxRstwrgepCuOvwQFvkBoj4l8428YIXUezg0HwLgA3FLkSqnmSUs2HD3vYYimk # fjC9G7WMcrRI8uPoIfleTGJ5iwIGn3/VCwIDAQABo4IBUTCCAU0wHwYDVR0jBBgw # FoAUu69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFCmRYP+KTfrr+aZquM/5 # 5ku9Sc4SMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMBEGA1UdIAQKMAgwBgYEVR0gADBMBgNVHR8ERTBDMEGg # P6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0 # aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0 # dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQG # CCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEM # BQADggIBAAI/AjnD7vjKO4neDG1NsfFOkk+vwjgsBMzFYxGrCWOvq6LXAj/MbxnD # PdYaCJT/JdipiKcrEBrgm7EHIhpRHDrU4ekJv+YkdK8eexYxbiPvVFEtUgLidQgF # TPG3UeFRAMaH9mzuEER2V2rx31hrIapJ1Hw3Tr3/tnVUQBg2V2cRzU8C5P7z2vx1 # F9vst/dlCSNJH0NXg+p+IHdhyE3yu2VNqPeFRQevemknZZApQIvfezpROYyoH3B5 # rW1CIKLPDGwDjEzNcweU51qOOgS6oqF8H8tjOhWn1BUbp1JHMqn0v2RH0aofU04y # MHPCb7d4gp1c/0a7ayIdiAv4G6o0pvyM9d1/ZYyMMVcx0DbsR6HPy4uo7xwYWMUG # d8pLm1GvTAhKeo/io1Lijo7MJuSy2OU4wqjtxoGcNWupWGFKCpe0S0K2VZ2+medw # bVn4bSoMfxlgXwyaiGwwrFIJkBYb/yud29AgyonqKH4yjhnfe0gzHtdl+K7J+IMU # k3Z9ZNCOzr41ff9yMU2fnr0ebC+ojwwGUPuMJ7N2yfTm18M04oyHIYZh/r9VdOEh # dwMKaGy75Mmp5s9ZJet87EUOeWZo6CLNuO+YhU2WETwJitB/vCgoE/tqylSNklzN # wmWYBp7OSFvUtTeTRkF8B93P+kPvumdh/31J4LswfVyA4+YWOUunMYICNDCCAjAC # AQEwgZIwfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3Rl # cjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQx # IzAhBgNVBAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5nIENBAhEA8wrETgdlCz4S # KlOPe+xYRTAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZ # BgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYB # BAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUYgHQHlh4Zq/2+Esg6xWNSljGI7QwDQYJ # KoZIhvcNAQEBBQAEggEAdbqZSwaXvQfXKyL2e76BUXBGofDhBsAfsiyiHJfZdgmz # qCZ/HdFodb4X7rbOzRbj8WKGjGWfsB8/6+dnyR0kapVM4s4v8t4ByeN1B41iIDIX # Mdb25+9EcKfHcPYoQMI59cmA4HASCZ9ABAPc0ZHa7ctTNLKTDSGTRI2ENUoP7R2u # xfZi7B8vF3pqIguX8VP7ITfzkK0uvWodjctzYg7DVd+yZsySBunCoQbzyNeTWkc2 # 6s0CJIWdgKX9DEnhhnaTM0v1+wkrWtzihfT7uGwwydMPMJqckRnADCXiSSHVLfOG # 7rXL8JNezSmraIEALimoKIAhmQ9C0cXuVYNudxwLGg== # SIG # End signature block |