{"id":9970,"date":"2026-10-19T00:00:46","date_gmt":"2026-10-19T00:00:46","guid":{"rendered":"https:\/\/pariswells.com\/blog\/?p=9970"},"modified":"2026-10-19T00:00:47","modified_gmt":"2026-10-19T00:00:47","slug":"investigate-gdap-csp-partner-licenses-for-overage","status":"publish","type":"post","link":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage","title":{"rendered":"Investigate GDAP CSP Partner Licenses for Overage"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code class=\"\">&lt;#\n.SYNOPSIS\n    For every customer in your GDAP tenant list, finds which ones already have\n    Windows Server or SQL Server licensing sold to them via Partner Center CSP\n    subscriptions.\n\n.DESCRIPTION\n    Reads the customer tenant list produced by Get-GDAPCustomerTenants.ps1,\n    signs into Partner Center ONCE as you\/the partner (not per customer\n    tenant - Partner Center scopes calls by -CustomerId, unlike the Azure\n    RBAC\/GDAP side which needs a context switch per tenant), and for each\n    customer lists their CSP subscriptions, keeping the ones whose offer name\n    matches a Server OS or SQL Server keyword and whose BillingType is\n    'License' (the model Windows Server\/SQL Server licensing is sold under in\n    Partner Center today).\n\n    Each kept row is also tagged LicenseModel = 'Perpetual' or 'Subscription'\n    (see Get-LicenseCoreDetails). This matters downstream: Azure Hybrid Benefit\n    requires Software Assurance or an equivalent Software Subscription - a\n    straight Perpetual purchase does NOT qualify as BYOL cover, so\n    Test-LicenseCompliance-AllCustomers.ps1 and\n    Find-HybridBenefitOpportunities-AllCustomers.ps1 only count Subscription\n    rows toward AHB-eligible licensing on file.\n\n    Run in its own PowerShell process, kept separate from Az.Accounts and\n    Microsoft.Graph, to avoid the known assembly conflicts between these\n    SDKs' shared Azure.Identity\/MSAL dependencies (same reason\n    Get-GDAPCustomerTenants.ps1 runs standalone).\n\n    Sign-in acquires one raw access token (New-PartnerAccessToken, using the\n    same well-known Microsoft public client ID Connect-PartnerCenter uses\n    internally) and feeds it into Connect-PartnerCenter, rather than calling\n    Connect-PartnerCenter interactively - doing both interactively in one\n    process throws \"An item with the same key has already been added\" from\n    the module's token cache. Keeping the raw token also lets this script\n    fall back to calling the Partner Center REST API directly for any\n    customer whose subscription list contains a status value the module's\n    typed model doesn't have an enum member for (\"Requested value 'X' was\n    not found\" - seen in the wild for 'Disabled', 'Expired', 'Benefit').\n    That's a module bug, not a per-customer issue: one unrecognized status\n    on ANY subscription throws for the customer's ENTIRE subscription list,\n    so without this fallback such a customer looks identical to \"no license\"\n    when the truth is \"we don't know.\"\n\n    A customer erroring here (e.g. \"not found\" \/ access denied) usually means\n    they're not your direct Partner Center customer of record - e.g. a 2-tier\n    CSP customer sitting under a different top-tier distributor. Logged to\n    the errors CSV and skipped, not a script bug.\n\n    VALIDATE BEFORE TRUSTING AT SCALE: run this once, then check its output\n    against 2-3 customers you *know* have Windows Server\/SQL Server licensing\n    sold, to confirm the offer-name keywords actually catch your catalog's\n    naming before relying on the full run's negative results.\n\n.PARAMETER CustomerCsv\n    Path to the customer tenant list from Get-GDAPCustomerTenants.ps1.\n\n.PARAMETER OutputCsv\n    Path to write the per-customer licensing findings to. Deliberately not\n    timestamped - it's a stable input consumed by\n    Find-HybridBenefitOpportunities-AllCustomers.ps1, same as GDAPCustomers.csv.\n\n.PARAMETER ServerOSKeywords\n    Offer-name substrings (case-insensitive) that count as Server OS licensing.\n\n.PARAMETER SqlKeywords\n    Offer-name substrings (case-insensitive) that count as SQL Server licensing.\n\n.PARAMETER ExcludeSuspended\n    By default a Suspended subscription still counts as \"licensing on file\"\n    (the record exists, it's just currently suspended). Pass this switch to\n    count only Active subscriptions. Deleted subscriptions never count.\n#>\n\n[CmdletBinding()]\nparam(\n    [string]$CustomerCsv,\n    [string]$OutputCsv,\n    [string[]]$ServerOSKeywords = @('Windows Server'),\n    [string[]]$SqlKeywords      = @('SQL Server'),\n    [switch]$ExcludeSuspended,\n    # Default is WAM (native Windows sign-in, supports passkey\/Windows Hello) - only\n    # needed when this script is launched by automation with no window handle for WAM's\n    # broker UI to attach to (fails with \"A window handle must be configured\"). Running\n    # this yourself in your own terminal should just work without this switch.\n    [switch]$DeviceCode\n)\n\n$ErrorActionPreference = 'Stop'\n\n# $PSScriptRoot can come back empty for -File invocations in this environment\n# (reproduced directly - it's not just this script); fall back to $MyInvocation,\n# which is reliable at script-body scope regardless of how the script was invoked.\n$ScriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Definition }\nif (-not $CustomerCsv) { $CustomerCsv = Join-Path $ScriptDir 'GDAPCustomers.csv' }\nif (-not $OutputCsv)   { $OutputCsv   = Join-Path $ScriptDir 'PartnerCenterLicensing.csv' }\n\nif (-not (Test-Path $CustomerCsv)) {\n    throw \"Customer list not found at '$CustomerCsv'. Run Get-GDAPCustomerTenants.ps1 first.\"\n}\n\nImport-Module PartnerCenter -RequiredVersion 3.0.10 -ErrorAction Stop\n\n$customers = Import-Csv -Path $CustomerCsv\nif (-not $customers -or $customers.Count -eq 0) {\n    Write-Warning \"No customer tenants in '$CustomerCsv'. Nothing to check.\"\n    return\n}\n\n$timestamp  = Get-Date -Format 'yyyyMMdd_HHmmss'\n$errorsPath = Join-Path (Split-Path $OutputCsv -Parent) \"PartnerCenterLicensing_Errors_$timestamp.csv\"\n\n$findings = [System.Collections.Generic.List[object]]::new()\n$errors   = [System.Collections.Generic.List[object]]::new()\n$statusesToKeep = if ($ExcludeSuspended) { @('Active') } else { @('Active', 'Suspended') }\n\nfunction Add-ErrorRow {\n    param($TenantId, $TenantName, $Message)\n    $errors.Add([pscustomobject]@{\n        TenantId   = $TenantId\n        TenantName = $TenantName\n        Message    = $Message\n    })\n}\n\nfunction Get-LicenseCategory {\n    param([string]$OfferName)\n    if (-not $OfferName) { return $null }\n    foreach ($kw in $ServerOSKeywords) { if ($OfferName -match [regex]::Escape($kw)) { return 'ServerOS' } }\n    foreach ($kw in $SqlKeywords)      { if ($OfferName -match [regex]::Escape($kw)) { return 'SQL' } }\n    return $null\n}\n\n# Parses core-license detail out of the offer name for the compliance math in\n# Test-LicenseCompliance-AllCustomers.ps1: edition (Standard\/Datacenter\/Enterprise),\n# whether it's a CAL (never a core license - CALs are a separate requirement and\n# must never be counted toward the per-VM core minimum), cores-per-unit (null\n# when the offer name doesn't state a per-core count at all, e.g. legacy\n# Server+CAL-model SKUs - those need manual review, not a guessed number), and\n# LicenseModel (Perpetual vs Subscription - see below).\n#\n# LicenseModel matters because Azure Hybrid Benefit (BYOL) requires Software\n# Assurance or an equivalent Software Subscription - a straight Perpetual purchase\n# (no SA) does NOT qualify, per Microsoft's AHB terms. In the CSP catalog the two\n# commerce models are distinguishable from the offer name alone: Software\n# Subscription SKUs are explicitly annual and carry a \"1 Year\"\/\"1 year\" suffix\n# (confirmed against the live data: those rows also carry a real ~1-year-out\n# CommitmentEndDate); Perpetual SKUs have no such suffix and report the\n# 31\/12\/9999 sentinel (or a blank) CommitmentEndDate, meaning no recurring term\n# at all. CALs are excluded from this either way since they're never core\n# licenses regardless of commerce model.\nfunction Get-LicenseCoreDetails {\n    param([string]$OfferName)\n    $isCal = $OfferName -match '\\bCAL\\b'\n    $edition =\n        if ($OfferName -match 'Datacenter') { 'Datacenter' }\n        elseif ($OfferName -match 'Enterprise') { 'Enterprise' }\n        elseif ($OfferName -match 'Standard') { 'Standard' }\n        else { 'Unknown' }\n    $coreMatch = [regex]::Match($OfferName, '(\\d+)\\s*[Cc]ore')\n    $coresPerUnit = if ($coreMatch.Success -and -not $isCal) { [int]$coreMatch.Groups[1].Value } else { $null }\n    $licenseModel = if ($OfferName -match '\\b1\\s*[Yy]ear\\b') { 'Subscription' } else { 'Perpetual' }\n    [pscustomobject]@{ IsCal = $isCal; Edition = $edition; CoresPerUnit = $coresPerUnit; LicenseModel = $licenseModel }\n}\n\n# The well-known Microsoft public client ID Connect-PartnerCenter itself uses for interactive\n# sign-in (found via reflection on Commands.ConnectPartnerCenter::PowerShellApplicationId).\n# Reused here so the raw-REST fallback authenticates as the same client.\n$partnerCenterAppId = '04b07795-8ddb-461a-bbee-02f9e1bf7b46'\n\nfunction Get-CustomerSubscriptionsRaw {\n    param([string]$CustomerId, [string]$AccessToken)\n    $headers = @{\n        Authorization      = \"Bearer $AccessToken\"\n        'MS-RequestId'     = [guid]::NewGuid().ToString()\n        'MS-CorrelationId' = [guid]::NewGuid().ToString()\n        Accept             = 'application\/json'\n    }\n    $resp = Invoke-RestMethod -Uri \"https:\/\/api.partnercenter.microsoft.com\/v1\/customers\/$CustomerId\/subscriptions\" -Headers $headers -Method Get -ErrorAction Stop\n    return $resp.items | ForEach-Object {\n        [pscustomobject]@{\n            OfferId           = $_.offerId\n            OfferName         = $_.offerName\n            BillingType       = $_.billingType\n            Status            = $_.status\n            Quantity          = $_.quantity\n            SubscriptionId    = $_.id\n            CommitmentEndDate = $_.commitmentEndDate\n        }\n    }\n}\n\nWrite-Host \"`n=== Sign in to Partner Center ===\" -ForegroundColor Cyan\nWrite-Host \"This is ONE sign-in as you\/the partner - not per customer tenant.\" -ForegroundColor Cyan\nif ($DeviceCode) {\n    Write-Host \"You'll get a device code - open the printed URL in your normal browser and enter it there.\" -ForegroundColor Cyan\n    Write-Host \"(A passkey\/Windows Hello option should be available on that sign-in page if you have one registered.)\" -ForegroundColor Cyan\n    $partnerToken = New-PartnerAccessToken -ApplicationId $partnerCenterAppId `\n        -Scopes 'https:\/\/api.partnercenter.microsoft.com\/user_impersonation' -UseDeviceAuthentication\n} else {\n    Write-Host \"A browser sign-in window will open - use passkey\/Windows Hello there if you have one registered.\" -ForegroundColor Cyan\n    $partnerToken = New-PartnerAccessToken -ApplicationId $partnerCenterAppId `\n        -Scopes 'https:\/\/api.partnercenter.microsoft.com\/user_impersonation' -UseAuthorizationCode\n}\nConnect-PartnerCenter -AccessToken $partnerToken.AccessToken | Out-Null\nWrite-Host \"Signed in to Partner Center.\" -ForegroundColor Green\nWrite-Host \"Customer tenants to check: $($customers.Count)\" -ForegroundColor Green\n\n$idx = 0\n$recoveredCount = 0\nforeach ($customer in $customers) {\n    $idx++\n    $tenantLabel = if ($customer.TenantName) { $customer.TenantName } else { $customer.TenantId }\n    Write-Host \"[$idx\/$($customers.Count)] $tenantLabel\" -ForegroundColor Yellow\n\n    $subs = $null\n    try {\n        $subs = Get-PartnerCustomerSubscription -CustomerId $customer.TenantId -ErrorAction Stop\n    } catch {\n        if ($_.Exception.Message -match \"Requested value '.*' was not found\") {\n            # Known PartnerCenter module bug: one subscription with a status value the typed\n            # model doesn't recognize throws for the customer's ENTIRE subscription list.\n            # Fall back to the raw REST API, which returns status as a plain string.\n            try {\n                $subs = Get-CustomerSubscriptionsRaw -CustomerId $customer.TenantId -AccessToken $partnerToken.AccessToken\n                $recoveredCount++\n                Write-Host \"  Recovered via raw REST fallback (module couldn't parse a subscription status)\" -ForegroundColor DarkCyan\n            } catch {\n                Write-Host \"  Skipped - raw REST fallback also failed: $($_.Exception.Message)\" -ForegroundColor DarkGray\n                Add-ErrorRow -TenantId $customer.TenantId -TenantName $tenantLabel -Message \"Typed call failed (unrecognized status); REST fallback also failed: $($_.Exception.Message)\"\n                continue\n            }\n        } else {\n            Write-Host \"  Skipped - $($_.Exception.Message)\" -ForegroundColor DarkGray\n            Add-ErrorRow -TenantId $customer.TenantId -TenantName $tenantLabel -Message $_.Exception.Message\n            continue\n        }\n    }\n\n    foreach ($sub in $subs) {\n        # -ne is case-insensitive by default in PowerShell, so this matches both the typed\n        # model's 'License' and the raw REST fallback's lowercase 'license'.\n        if ($sub.BillingType.ToString() -ne 'License') { continue }\n        if ($sub.Status.ToString() -notin $statusesToKeep) { continue }\n\n        $category = Get-LicenseCategory -OfferName $sub.OfferName\n        if (-not $category) { continue }\n\n        $core = Get-LicenseCoreDetails -OfferName $sub.OfferName\n        $totalCores = if ($core.CoresPerUnit) { $core.CoresPerUnit * [int]$sub.Quantity } else { $null }\n        $isLapsed = $false\n        if ($sub.CommitmentEndDate) {\n            try { $isLapsed = ([datetime]$sub.CommitmentEndDate) -lt (Get-Date) } catch {}\n        }\n\n        $findings.Add([pscustomobject]@{\n            TenantId          = $customer.TenantId\n            TenantName        = $tenantLabel\n            LicenseCategory   = $category\n            OfferId           = $sub.OfferId\n            OfferName         = $sub.OfferName\n            Edition           = $core.Edition\n            IsCal             = $core.IsCal\n            CoresPerUnit      = $core.CoresPerUnit\n            LicenseModel      = $core.LicenseModel\n            Quantity          = $sub.Quantity\n            TotalCores        = $totalCores\n            Status            = $sub.Status\n            IsLapsed          = $isLapsed\n            SubscriptionId    = $sub.SubscriptionId\n            CommitmentEndDate = $sub.CommitmentEndDate\n        })\n        Write-Host \"    [$category] $($sub.OfferName) x$($sub.Quantity) ($($sub.Status))\" -ForegroundColor Green\n    }\n}\n\n$findings | Export-Csv -Path $OutputCsv -NoTypeInformation -Encoding UTF8\n$errors   | Export-Csv -Path $errorsPath -NoTypeInformation -Encoding UTF8\n\nWrite-Host \"`n=== Done ===\" -ForegroundColor Cyan\nWrite-Host \"Customers checked                      : $($customers.Count)\" -ForegroundColor Green\nWrite-Host \"Matching Server OS\/SQL license records  : $($findings.Count)\" -ForegroundColor Green\nWrite-Host \"Recovered via REST fallback             : $recoveredCount\" -ForegroundColor DarkCyan\nWrite-Host \"Customers with a lookup error           : $($errors.Count)\" -ForegroundColor Yellow\nWrite-Host \"Licensing file (feeds the next script)  : $OutputCsv\" -ForegroundColor Green\nWrite-Host \"Errors log                              : $errorsPath\" -ForegroundColor Yellow\n\nDisconnect-PartnerCenter | Out-Null\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-9970","post","type-post","status-publish","format-standard","hentry","category-research"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"paris\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Welcome to Pariswells.com |\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-19T00:00:46+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-19T00:00:47+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#article\",\"name\":\"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com\",\"headline\":\"Investigate GDAP CSP Partner Licenses for Overage\",\"author\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/author\\\/paris#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#organization\"},\"datePublished\":\"2026-10-19T00:00:46+00:00\",\"dateModified\":\"2026-10-19T00:00:47+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#webpage\"},\"articleSection\":\"Research\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/category\\\/research#listItem\",\"name\":\"Research\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/category\\\/research#listItem\",\"position\":2,\"name\":\"Research\",\"item\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/category\\\/research\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#listItem\",\"name\":\"Investigate GDAP CSP Partner Licenses for Overage\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#listItem\",\"position\":3,\"name\":\"Investigate GDAP CSP Partner Licenses for Overage\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/category\\\/research#listItem\",\"name\":\"Research\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#organization\",\"name\":\"Welcome to Pariswells.com\",\"url\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/author\\\/paris#author\",\"url\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/author\\\/paris\",\"name\":\"paris\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/93b8ee3f592ac401167f870452bd82d43de80152cd3524e2853403658ada9984?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"paris\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#webpage\",\"url\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage\",\"name\":\"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/research\\\/investigate-gdap-csp-partner-licenses-for-overage#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/author\\\/paris#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/author\\\/paris#author\"},\"datePublished\":\"2026-10-19T00:00:46+00:00\",\"dateModified\":\"2026-10-19T00:00:47+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/\",\"name\":\"Welcome to Pariswells.com\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/pariswells.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com","description":"","canonical_url":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#article","name":"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com","headline":"Investigate GDAP CSP Partner Licenses for Overage","author":{"@id":"https:\/\/pariswells.com\/blog\/author\/paris#author"},"publisher":{"@id":"https:\/\/pariswells.com\/blog\/#organization"},"datePublished":"2026-10-19T00:00:46+00:00","dateModified":"2026-10-19T00:00:47+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#webpage"},"isPartOf":{"@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#webpage"},"articleSection":"Research"},{"@type":"BreadcrumbList","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/pariswells.com\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/category\/research#listItem","name":"Research"}},{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/category\/research#listItem","position":2,"name":"Research","item":"https:\/\/pariswells.com\/blog\/category\/research","nextItem":{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#listItem","name":"Investigate GDAP CSP Partner Licenses for Overage"},"previousItem":{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#listItem","position":3,"name":"Investigate GDAP CSP Partner Licenses for Overage","previousItem":{"@type":"ListItem","@id":"https:\/\/pariswells.com\/blog\/category\/research#listItem","name":"Research"}}]},{"@type":"Organization","@id":"https:\/\/pariswells.com\/blog\/#organization","name":"Welcome to Pariswells.com","url":"https:\/\/pariswells.com\/blog\/"},{"@type":"Person","@id":"https:\/\/pariswells.com\/blog\/author\/paris#author","url":"https:\/\/pariswells.com\/blog\/author\/paris","name":"paris","image":{"@type":"ImageObject","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/93b8ee3f592ac401167f870452bd82d43de80152cd3524e2853403658ada9984?s=96&d=mm&r=g","width":96,"height":96,"caption":"paris"}},{"@type":"WebPage","@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#webpage","url":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage","name":"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/pariswells.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage#breadcrumblist"},"author":{"@id":"https:\/\/pariswells.com\/blog\/author\/paris#author"},"creator":{"@id":"https:\/\/pariswells.com\/blog\/author\/paris#author"},"datePublished":"2026-10-19T00:00:46+00:00","dateModified":"2026-10-19T00:00:47+00:00"},{"@type":"WebSite","@id":"https:\/\/pariswells.com\/blog\/#website","url":"https:\/\/pariswells.com\/blog\/","name":"Welcome to Pariswells.com","inLanguage":"en-US","publisher":{"@id":"https:\/\/pariswells.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Welcome to Pariswells.com |","og:type":"article","og:title":"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com","og:url":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage","article:published_time":"2026-10-19T00:00:46+00:00","article:modified_time":"2026-10-19T00:00:47+00:00","twitter:card":"summary","twitter:title":"Investigate GDAP CSP Partner Licenses for Overage | Welcome to Pariswells.com"},"aioseo_meta_data":{"post_id":"9970","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-10-19 00:00:07","updated":"2026-10-19 00:00:47","primary_term":null,"seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/pariswells.com\/blog\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/pariswells.com\/blog\/category\/research\" title=\"Research\">Research<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tInvestigate GDAP CSP Partner Licenses for Overage\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/pariswells.com\/blog\/"},{"label":"Research","link":"https:\/\/pariswells.com\/blog\/category\/research"},{"label":"Investigate GDAP CSP Partner Licenses for Overage","link":"https:\/\/pariswells.com\/blog\/research\/investigate-gdap-csp-partner-licenses-for-overage"}],"_links":{"self":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/9970","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/comments?post=9970"}],"version-history":[{"count":1,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/9970\/revisions"}],"predecessor-version":[{"id":9971,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/9970\/revisions\/9971"}],"wp:attachment":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/media?parent=9970"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/categories?post=9970"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/tags?post=9970"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}