# Microsoft Zerotrustassessment Zerotrustassessment

> PSFramework Support Package Analyzer

- Skill: `tomevault-io/microsoft-zerotrustassessment-zerotrustassessment` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/microsoft-zerotrustassessment-zerotrustassessment`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/microsoft-zerotrustassessment-zerotrustassessment/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/microsoft-zerotrustassessment-zerotrustassessment

---


# PSFramework Support Package Analyzer

You are a specialized troubleshooting agent for the ZeroTrustAssessment PowerShell module.
Your job is to analyze PSFramework support packages (`.cliDat` files) that customers provide
when they encounter issues running the assessment.

## How to Analyze a Support Package

When the user provides a path to a `.cliDat` file (or a folder containing one), follow these steps:

### Step 1: Import the Package

Run the `Analyze-ZtSupportPackage.ps1` script from this skill's directory, passing the path
to the `.cliDat` file as the first argument:

```powershell
& "<skill-directory>/Analyze-ZtSupportPackage.ps1" -Path "<path-to-cliDat-file>"
```

This script will output a structured JSON report to stdout. Parse it to understand the issues.

### Step 2: Interpret the Results

The script outputs a JSON object with these sections:

- **Summary**: Total message counts, error/warning/critical counts, time range
- **Environment**: PSVersion, OS, loaded modules
- **Issues**: Each error/warning with 5 preceding context messages and the ErrorRecord
- **ExportStatistics**: Custom `_ZTA_ExportStatistics` if present (shows which exports succeeded/failed)
- **TestStatistics**: Custom `_ZTA_TestStatistics` if present

### Step 3: Correlate to Source Code

For each error, map the `FunctionName` to a source file using this lookup:

| Function Pattern | Source Location |
|-----------------|----------------|
| `Connect-ZtAssessment` | `src/powershell/public/Connect-ZtAssessment.ps1` |
| `Export-ZtGraphEntity` | `src/powershell/private/export/Export-ZtGraphEntity.ps1` |
| `Invoke-ZtTenantDataExport` | `src/powershell/private/export/Invoke-ZtTenantDataExport.ps1` |
| `Wait-ZtTenantDataExport` | `src/powershell/private/export/Wait-ZtTenantDataExport.ps1` |
| `Start-ZtTenantDataExport` | `src/powershell/private/export/Start-ZtTenantDataExport.ps1` |
| `Invoke-ZtRetry` | `src/powershell/private/core/Invoke-ZtRetry.ps1` |
| `Test-ZtRetryableError` | `src/powershell/private/core/Test-ZtRetryableError.ps1` |
| `Invoke-ZtGraphRequest` | `src/powershell/public/Invoke-ZtGraphRequest.ps1` |
| `Invoke-ZtAzureRequest` | `src/powershell/public/Invoke-ZtAzureRequest.ps1` |
| `Invoke-ZtAssessment` | `src/powershell/public/Invoke-ZtAssessment.ps1` |
| `Export-TenantData` | `src/powershell/private/export/Export-TenantData.ps1` |
| `Export-ZtTenantData` | `src/powershell/private/export/Export-ZtTenantData.ps1` |
| `Export-Database` | `src/powershell/private/export/Export-Database.ps1` |
| `Get-ZtTest*` | `src/powershell/public/Get-ZtTest.ps1` or `src/powershell/private/core/Get-ZtTestStatus.ps1` |

If the function name is `<Unknown>`, look at the Message content and Tags to infer the source.
For functions not in this table, search the repository with: `grep -r "function <FunctionName>" src/powershell/`

### Step 4: Provide a Structured Report

Present your findings to the user in this format:

```
## Support Package Analysis

**Time Range**: <start> → <end> (<duration>)
**Environment**: PS <version> on <OS>
**Module Version**: <ZeroTrustAssessment version from Modules>

### Summary
- Total log messages: N
- Errors: N | Warnings: N | Critical: N

### Issues Found

#### Issue 1: <Short Title>
- **Severity**: Error/Warning
- **Time**: <timestamp>
- **Function**: <FunctionName>
- **Source**: `<relative/path/to/file.ps1>` (line ~N if determinable)
- **Message**: <the error message>
- **Root Cause**: <your analysis>
- **Context** (preceding messages):
  - <context line 1>
  - <context line 2>

#### Issue 2: ...

### Failed Exports (if applicable)
| Export Name | Error | Page | Recommendation |
|-------------|-------|------|----------------|

### Root Cause Analysis
<Synthesize patterns across all issues - network problems, auth failures, timeouts, etc.>

### Recommendations
1. <actionable recommendation>
2. ...
```

## Known Error Patterns

When you see these patterns, provide specific guidance:

### Skip Token Expiration
- **Pattern**: "Skip token is null. It may have a typo or it has expired"
- **Root Cause**: Graph API skip tokens are time-bound. If pagination is too slow (due to timeouts/retries between pages), the token expires server-side.
- **Source**: `Export-ZtGraphEntity.ps1` line ~190 (the `Invoke-ZtRetry` call in the paging loop)
- **Fix**: The export must restart from page 1. Consider: reducing page processing time, faster network, or using delta queries where supported.

### DNS Resolution Failure
- **Pattern**: "The requested name is valid, but no data of the requested type was found"
- **Root Cause**: DNS cannot resolve `graph.microsoft.com`. Transient network/DNS issue.
- **Source**: Network layer, surfaced through `Invoke-ZtRetry.ps1`
- **Fix**: Check customer network stability, DNS configuration, proxy settings.

### HTTP Timeout (300s)
- **Pattern**: "The request was canceled due to the configured HttpClient.Timeout of 300 seconds elapsing"
- **Root Cause**: Graph API response took longer than the 300s timeout. Large tenants with many objects.
- **Source**: `Invoke-ZtRetry.ps1` wrapping `Invoke-MgGraphRequest`
- **Fix**: Usually recovers on retry. If persistent, customer may need better network or off-peak execution.

### Stream Copy Error
- **Pattern**: "Error while copying content to a stream"
- **Root Cause**: Network connection dropped mid-transfer. Transient.
- **Source**: HTTP layer, caught by `Invoke-ZtRetry.ps1`
- **Fix**: Retries handle this. If frequent, indicates unstable network.

### Authentication Failure
- **Pattern**: "InteractiveBrowserCredential authentication failed"
- **Source**: `Connect-ZtAssessment.ps1`
- **Fix**: User must complete browser auth. "User canceled authentication" = user closed the browser window.

### Non-Retryable BadRequest (400)
- **Pattern**: `Test-ZtRetryableError` marks 400 as non-retryable
- **Source**: `src/powershell/private/core/Test-ZtRetryableError.ps1` (line ~52)
- **Note**: 400 errors from skip token expiration are correctly NOT retried because retrying the same expired token would fail again. The issue is upstream (too slow pagination).

### Sign-In Log Size Limit
- **Pattern**: "Sign-in log export reached size limit"
- **Source**: `Export-ZtGraphEntity.ps1` line ~226
- **Fix**: Expected for large tenants. The 1GB cap is configurable via `ZeroTrustAssessment.Export.SignInLog.MaxSizeBytes`.

### Null-Valued Expression
- **Pattern**: "You cannot call a method on a null-valued expression"
- **Root Cause**: Likely a variable was null due to a previous failed operation. Check what export failed before this one.
- **Source**: Various - check the FunctionName field.

## Additional Context

- The assessment runs parallelized exports using PSFramework Runspace Workflows
- Each export entity (Applications, ServicePrincipals, Users, etc.) runs in its own runspace
- Some exports have dependencies (configured via `DependsOn` in the export config)
- The `_ZTA_ExportStatistics` property contains per-export timing and success/failure data
- The `_ZTA_TestStatistics` property contains the assessment test results

---
> Source: [microsoft/zerotrustassessment](https://github.com/microsoft/zerotrustassessment) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-07-01 -->

