PowerShell脚本迁移网络后ConvertFrom-Json报错求助
Let's break down why you're hitting that ArgumentException with ConvertFrom-Json and how to fix it. The error means PowerShell can't parse the content returned by the API into valid JSON—so first, we need to figure out what the API is actually sending back now that you've moved networks.
Step 1: Debug the API Response Content
The most likely culprit is that your new network environment (firewall, proxy, IP restrictions) is causing the API to return an error page (HTML) instead of the expected JSON. Let's add debug code to capture what's coming back:
Modify the section after Invoke-WebRequest in your script:
try { Write-Host "[STATUS] Requesting results for $($line)..." $Response = Invoke-WebRequest -Uri "$($API_URL)?number=$($line)&enumeration_type=&taxonomy_description=&first_name=&last_name=&organization_name=&address_purpose=&city=&state=&postal_code=&country_code=&limit=&skip=" # Add debug logging to check what the API is returning Write-Host "Debug: Response Status Code: $($Response.StatusCode)" $debugFile = Join-Path $scriptDir "debug_response_$line.txt" $Response.Content | Out-File -Path $debugFile -Encoding utf8 Write-Host "Debug: Saved raw response to $debugFile" } catch { Write-Host "`n[!!ERROR!!] Error communicating with $($API_URL)`n" # Show detailed error info instead of just exiting Write-Host "Full error details: $_" exit 1 }
Run the script again, then open the generated debug_response_*.txt files:
- If you see HTML (e.g., 403 Forbidden, 500 Server Error, or a proxy login page), your network is blocking the API request. You'll need to work with your network team to allow traffic to
https://npiregistry.cms.hhs.gov, or configure PowerShell to use your network's proxy:# Add this at the top of your script if you need a proxy $proxyUri = "http://your-proxy-server:port" $webSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession $webSession.Proxy = New-Object System.Net.WebProxy($proxyUri) # Then use -WebSession $webSession in Invoke-WebRequest $Response = Invoke-WebRequest -Uri ... -WebSession $webSession - If the content is garbled text, it's an encoding issue. Fix this by forcing UTF-8 encoding when reading the response:
# Replace the ConvertFrom-Json line with this $jsonBytes = $Response.RawContentStream.ToArray() $jsonContent = [System.Text.Encoding]::UTF8.GetString($jsonBytes) $NPI_Results = ConvertFrom-Json -InputObject $jsonContent - If the content is valid JSON but has a different structure than expected, the API might have changed—but since this worked before migration, this is less likely.
Step 2: Fix Other Potential Issues
While you're at it, let's clean up a few other things that could cause problems:
- Variable Case Inconsistency: You mix
$NPI_Resultsand$NPI_RESULTS(e.g.,$NPI_RESULTS.results.basic.last_updated). PowerShell is case-insensitive, but this can lead to confusion. Stick to one consistent case. - Manual CSV Splicing: Building the CSV by concatenating strings is error-prone (e.g., if a name or address has commas/quotes). Use PowerShell objects instead for cleaner, safer CSV output:
# Initialize an array to hold results $outputArray = @() # Inside your foreach loop, when a result is found: if ($NPI_Results.result_count -eq "1") { $resultObj = [PSCustomObject]@{ "NPI NUMBER" = $NPI_Results.results.number "RESULT" = "SUCCESS" "LAST UPDATE" = $NPI_Results.results.basic.last_updated "NAME" = $NPI_Results.results.basic.name "DESCRIPTION" = $NPI_Results.results.taxonomies.desc "CREDENTIAL" = $NPI_Results.results.basic.credential "STATUS" = $NPI_Results.results.basic.status "ADDRESS 1 LABEL" = $NPI_Results.results.addresses[0].address_purpose "ADDRESS 1" = "$($NPI_Results.results.addresses[0].address_1), $($NPI_Results.results.addresses[0].address_2), $($NPI_Results.results.addresses[0].city), $($NPI_Results.results.addresses[0].state), $($NPI_Results.results.addresses[0].postal_code), $($NPI_Results.results.addresses[0].country_code)" "TELEPHONE 1" = $NPI_Results.results.addresses[0].telephone_number "ADDRESS 2 LABEL" = if ($NPI_Results.results.addresses.Count -gt 1) { $NPI_Results.results.addresses[1].address_purpose } else { $null } "ADDRESS 2" = if ($NPI_Results.results.addresses.Count -gt 1) { "$($NPI_Results.results.addresses[1].address_1), $($NPI_Results.results.addresses[1].address_2), $($NPI_Results.results.addresses[1].city), $($NPI_Results.results.addresses[1].state), $($NPI_Results.results.addresses[1].postal_code), $($NPI_Results.results.addresses[1].country_code)" } else { $null } "TELEPHONE 2" = if ($NPI_Results.results.addresses.Count -gt 1) { $NPI_Results.results.addresses[1].telephone_number } else { $null } } $outputArray += $resultObj } else { $resultObj = [PSCustomObject]@{ "NPI NUMBER" = $line "RESULT" = "NONE" "LAST UPDATE" = $null "NAME" = $null "DESCRIPTION" = $null "CREDENTIAL" = $null "STATUS" = $null "ADDRESS 1 LABEL" = $null "ADDRESS 1" = $null "TELEPHONE 1" = $null "ADDRESS 2 LABEL" = $null "ADDRESS 2" = $null "TELEPHONE 2" = $null } $outputArray += $resultObj } # At the end, export the array to CSV $outputArray | Export-Csv -Path $OUTPUT_FILE -NoTypeInformation -Encoding utf8
Step 3: Verify the API Endpoint
Double-check that $API_URL = "https://npiregistry.cms.hhs.gov/api/resultsDemo2/" is still valid. The official NPI API endpoint is usually https://npiregistry.cms.hhs.gov/api/—if the demo endpoint has restricted access, switching to the main API might resolve issues (just adjust the URI to $API_URL?number=$line).
内容的提问来源于stack exchange,提问作者Clint Guillory

