Hi @Manishsharm -
If $env:Request is now definitely populated (after forcing the full 64-bit powershell.exe path) but $requestObject stays $null, the usual culprit is that the SailPoint Utils assembly isn’t actually loaded in that PowerShell process on your Windows 2022 host. On older hosts it’s easy to “get lucky” because of working-directory/probing behavior; on 2022/.NET 4.8 you often have to explicitly load Utils.dll before you can New-Object Sailpoint.Utils.objects.AccountRequest(...). SailPoint’s own samples show doing exactly that with Add-Type -Path ...\Utils.dll. (Writing a Script)
Below is a tight, copy-paste block that (1) resolves the actual IQService install directory, (2) unblocks and loads Utils.dll, (3) sanity-checks the types are visible, and (4) constructs the objects without using the XmlUtil helper (to avoid one more dependency while we debug):
# Fail fast and log real errors (IQService can swallow non-terminating errors otherwise)
$ErrorActionPreference = 'Stop'
# 1) Find IQService home and Utils.dll robustly from the service definition
$svc = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\IQService' -Name ImagePath
$svcPath = ($svc.ImagePath -replace '^"|"$','') # strip quotes
$iqHome = Split-Path $svcPath # e.g. C:\SailPoint\IQService
$utils = Join-Path $iqHome 'Utils.dll'
# 2) Unblock and load Utils.dll (unsigned/“downloaded” DLLs can be blocked on 2022)
if (Get-Item $utils -Stream Zone.Identifier -ErrorAction SilentlyContinue) { Unblock-File $utils }
Add-Type -Path $utils
# 3) Prove the SailPoint types are now visible
if (-not [Type]::GetType('Sailpoint.Utils.objects.AccountRequest', $false)) {
throw "Sailpoint.Utils.objects.AccountRequest type not visible. Loaded from: $utils"
}
# 4) Build readers without XmlUtil to reduce moving parts while debugging
$sReader = New-Object System.IO.StringReader([string]$env:Request)
$xmlReader = New-Object System.Xml.XmlTextReader($sReader)
# 5) Construct the request/result objects
$requestObject = New-Object 'Sailpoint.Utils.objects.AccountRequest' ($xmlReader)
# Optional: dump a quick proof
"Request XML length: $([string]$env:Request).Length"
"RequestObject type : " + ($requestObject.GetType().FullName)
Why this usually fixes it
-
Utils.dllmust be loaded for thoseSailpoint.Utils.*types to exist. Without it,New-Objecthas nothing to construct and—depending on error handling—can look like “it returns null”. SailPoint’s samples and docs explicitlyAdd-Type -Path ...\Utils.dllbefore usingAccountRequest/ServiceResult. -
On Server 2022/.NET 4.8, default probing is less forgiving. If the PS working directory isn’t the IQService bin (very common when you hard-pin the
powershell.exepath), the assembly won’t auto-resolve, so explicit path loading is required. (SailPoint docs and community threads showAdd-Type -Path "C:\SailPoint\IQService\Utils.dll"patterns.) (Powershell script : Accessing attributes within accountRequest) -
Also check for Windows “blocked” file state on
Utils.dll(Zone.Identifier). That’s bitten a lot of people post-upgrade on hardened 2022 images; unblocking resolves the silent load failure. (We are seeing an exception while provisioning an identity to AD after the recent IQ service upgrade)
If you still hit issues after Add-Type
Run these quick probes to pinpoint the exact failure:
# 1) Is the SailPoint assembly actually loaded?
[AppDomain]::CurrentDomain.GetAssemblies() | Where-Object FullName -match 'Utils' |
Select-Object FullName, Location
# 2) Do we see the types?
[AppDomain]::CurrentDomain.GetAssemblies() |
ForEach-Object { $_.GetTypes() } |
Where-Object FullName -like 'Sailpoint.*' |
Sort-Object FullName
# 3) Does the XML parse natively? (rule out truncation/bad XML)
try { [xml]$reqXml = $env:Request; $reqXml.DocumentElement.Name } catch { $_ | fl * -Force; throw }
# 4) How big is Request? (environment vars over ~32K can get you into trouble)
([string]$env:Request).Length
-
If (1)/(2) show no SailPoint types, the assembly is not loading (wrong path, blocked DLL, or policy).
-
If (3) fails, your request XML is malformed/truncated (less likely now that
$env:Requestprints, but worth checking). -
If (4) shows a very large value (tens of thousands of chars), you may be bumping environment-block limits; consider a non-OO fallback (use the
SP_*request variables, which IQService emits for non-OO scripts) to avoid parsing the full XML. (Before After Script)
Bonus: keep XmlUtil if you prefer it
Once Utils.dll is loading cleanly, you can go back to your original style:
$sReader = New-Object System.IO.StringReader([string]$env:Request)
$xmlReader = [sailpoint.Utils.xml.XmlUtil]::getReader($sReader)
$requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader)
$resultObject = New-Object Sailpoint.Utils.objects.ServiceResult
(But verify the type exists first; the reflection snippet above will tell you.)
TL;DR
On Windows 2022, explicitly load Utils.dll before New-Object Sailpoint.Utils.objects.AccountRequest(...), ensure the DLL isn’t blocked, and confirm the types are visible—then your existing code will work the same as it did on 2012. SailPoint’s docs and examples show this Add-Type -Path ...\Utils.dll step as required.
If you paste the output of the 4 probe snippets (assemblies/types/XML/length), I’ll tell you exactly which link in the chain is breaking.
Thanks