u/jriker2

Can't figure out why complaining about catch block missing

I have this code I'm trying to generate for pulling information out of Intune. It gets most of the way thru but it's complaining with this:

>

At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:293 char:14

>+ }

>+ ~

>The Try statement is missing its Catch or Finally block.

>At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:294 char:8

>+ }

>+ ~

>Unexpected token '}' in expression or statement.

>At C:\temp\Intune\Get-UnassignediOSDEPDevices.ps1:295 char:3

>+ }

>+ ~

>Unexpected token '}' in expression or statement.

>+ CategoryInfo : ParserError: (:) [], ParseException

>+ FullyQualifiedErrorId : MissingCatchOrFinally

I went thru and lined up all the brackets and seems like it's correct but haven't been able to nail it down. Anyone else seeing what's going on?

<#

.SYNOPSIS

Lists all unassigned devices from Apple Device Enrollment Program (DEP) tokens in Microsoft Intune

.DESCRIPTION

This script connects to the Microsoft Graph API and retrieves all imported Apple device identities

from enrolled DEP tokens, then filters for devices that have not been assigned a user yet.

.PARAMETER ShowAllTokens

Display devices from all DEP tokens even if only one exists

.EXAMPLE

.\Get-UnassignediOSDEPDevices.ps1

Lists all unassigned iOS DEP devices across all enrollment program tokens

.EXAMPLE

.\Get-UnassignediOSDEPDevices.ps1 -ShowAllTokens

Shows devices with additional token information

#>

[CmdletBinding()]

param(

[Parameter(Mandatory = $false)]

[switch]$ShowAllTokens,

[Parameter(Mandatory = $false)]

[string]$ExportPath

)

# ============================================================================

# MODULE CHECK AND IMPORT

# ============================================================================

Write-Host "\n========================================" -ForegroundColor Cyan`

Write-Host " iOS DEP Unassigned Devices Report" -ForegroundColor Cyan

Write-Host "========================================\n" -ForegroundColor Cyan`

$RequiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Intune")

foreach ($Module in $RequiredModules)

{

if (-not (Get-Module -ListAvailable -Name $Module))

{

Write-Warning "Module '$Module' not found. Installing..."

Install-Module -Name $Module -Force -Scope CurrentUser -AllowClobber -ErrorAction SilentlyContinue

}

Import-Module -Name $Module -Force -ErrorAction Stop

}

# ============================================================================

# AUTHENTICATION

# ============================================================================

Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Yellow

try

{

Connect-MgGraph -Scopes @("DeviceManagementServiceConfig.Read.All",

"DeviceManagementManagedDevices.Read.All") -NoWelcome -ErrorAction Stop

}

catch

{

Write-Error "Failed to connect to Microsoft Graph: $_"

exit 1

}

# ============================================================================

# HELPER FUNCTIONS

# ============================================================================

function Get-MgGraphAllPages

{

param(

[Parameter(Mandatory = $true)]

[string]$Uri,

[int]$DelayMs = 50

)

$AllResults = @()

$NextLink = $Uri

do

{

try

{

if ($null -ne $NextLink)

{

Start-Sleep -Milliseconds $DelayMs

}

$Response = Invoke-MgGraphRequest -Uri $NextLink -Method GET

if ($Response.value)

{

$AllResults += $Response.value

}

else

{

$AllResults += $Response

}

$NextLink = $Response.'@odata.nextLink'

}

catch

{

Write-Warning "Error fetching data from $NextLink : $_"

break

}

}

while ($null -ne $NextLink)

return $AllResults

}

function Get-UnassignedDevicesFromToken

{

param(

[Parameter(Mandatory = $true)]

[string]$TokenId,

[Parameter(Mandatory = $true)]

[string]$TokenName,

[Parameter(Mandatory = $false)]

[string]$ExpirationDate

)

try

{

Write-Host " Retrieving devices from token: $TokenName..." -ForegroundColor Gray

# Get imported Apple device identities for this DEP token

$Uri = "https://graph.microsoft.com/beta/deviceManagement/depOnboardingSettings/$($TokenId)/importedAppleDeviceIdentities"

$Devices = Get-MgGraphAllPages -Uri $Uri

Write-Host " Found $($Devices.Count) devices in this token..." -ForegroundColor Gray

# Filter for unassigned devices (no userPrincipalName assigned)

$UnassignedDevices = @()

foreach ($Device in $Devices)

{

# A device is considered unassigned if it has no userPrincipalName or addressableUserName

$IsAssigned = $false

if ([string]::IsNullOrEmpty($Device.userPrincipalName))

{

$IsAssigned = $false

}

elseif ([string]::IsNullOrEmpty($Device.addressableUserName))

{

$IsAssigned = $false

}

else

{

# Check if the user is assigned but not yet enrolled

$IsAssigned = $true

}

if (-not $IsAssigned)

{

$UnassignedDevices += [PSCustomObject]@{

TokenName = $TokenName

DeviceId = $Device.id

SerialNumber = $Device.serialNumber

Model = $Device.model

Manufacturer = $Device.manufacturer

EnrollmentState = $Device.enrollmentState

UserPrincipalName = if ([string]::IsNullOrEmpty($Device.userPrincipalName)) { "<Unassigned>" } else { $Device.userPrincipalName }

AddressableUserName = if ([string]::IsNullOrEmpty($Device.addressableUserName)) { "<Not Set>" } else { $Device.addressableUserName }

CreatedDateTime = $Device.createdDateTime

LastContactedDate = $Device.lastContactedDateTime

}

}

}

return $UnassignedDevices

}

catch

{

Write-Warning "Error retrieving devices from token '$TokenName': $_"

return @()

}

}

# ============================================================================

# MAIN SCRIPT LOGIC

# ============================================================================

try

{

# Step 1: Get all DEP tokens (Enrollment Program Tokens)

Write-Host "\n[Step 1] Retrieving Enrollment Program Tokens..." -ForegroundColor Yellow`

$DepTokensUri = "https://graph.microsoft.com/beta/deviceManagement/depOnboardingSettings"

$AllTokens = Get-MgGraphAllPages -Uri $DepTokensUri

if ($AllTokens.Count -eq 0)

{

Write-Host "\n[!] No Enrollment Program Tokens found in this tenant." -ForegroundColor Red`

exit 1

}

Write-Host " Found $($AllTokens.Count) DEP token(s)" -ForegroundColor Green

# Step 2: Get all enrolled iOS devices from Intune for comparison

Write-Host "\n[Step 2] Retrieving managed iOS devices..." -ForegroundColor Yellow`

$ManagedDevicesUri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices?\$filter=operatingSystem eq 'iOS'"`

$EnrolledDevices = Get-MgGraphAllPages -Uri $ManagedDevicesUri

Write-Host " Found $($EnrolledDevices.Count) managed iOS devices" -ForegroundColor Green

# Step 3: Build comparison dictionary for already enrolled devices

$EnrolledSerialNumbers = @{}

foreach ($Device in $EnrolledDevices)

{

if ([string]::IsNullOrEmpty($Device.serialNumber))

{

continue

}

$EnrolledSerialNumbers[$Device.serialNumber] = $true

}

# Step 4: Get unassigned devices from each token

Write-Host "\n[Step 3] Finding unassigned devices..." -ForegroundColor Yellow`

$AllUnassignedDevices = @()

foreach ($Token in $AllTokens)

{

`$DeviceList = Get-UnassignedDevicesFromToken ``

`-TokenId $Token.id ``

`-TokenName $Token.tokenName ``

-ExpirationDate $Token.tokenExpirationDateTime

# Filter out devices that are already enrolled (in managedDevices)

$FilteredDevices = @()

foreach ($Device in $DeviceList)

{

if (-not $EnrolledSerialNumbers.ContainsKey($Device.SerialNumber))

{

$FilteredDevices += $Device

}

}

$AllUnassignedDevices += $FilteredDevices

Write-Host " Token '$($Token.tokenName)': $($DeviceList.Count) unassigned devices" -ForegroundColor Gray

}

# Step 5: Display results summary

Write-Host "\n[Step 4] Results Summary..." -ForegroundColor Yellow`

if ($AllUnassignedDevices.Count -eq 0)

{

Write-Host "\n[✓] All DEP devices have been assigned a user!" -ForegroundColor Green`

}

else

{

# Group by token for summary display

$TokenSummary = $AllUnassignedDevices | Group-Object TokenName

Write-Host "Total unassigned devices: $($AllUnassignedDevices.Count)" -ForegroundColor Red

Write-Host "\nBreakdown by Enrollment Program Token:" -ForegroundColor Yellow`

foreach ($Group in $TokenSummary)

{

Write-Host " - $($Group.Name): $($Group.Count) unassigned devices" -ForegroundColor Cyan

}

# Display detailed list of unassigned devices

Write-Host "\n========================================`n" -ForegroundColor Cyan`

`$AllUnassignedDevices | Sort-Object TokenName, SerialNumber | Format-Table ``

`-AutoSize ``

-Property @(

@{Label="Token";Expression={$_.TokenName}},

@{Label="Serial Number";Expression={$_.SerialNumber}},

@{Label="Model";Expression={$_.Model}},

@{Label="Manufacturer";Expression={$_.Manufacturer}},

@{Label="Enrollment State";Expression={$_.EnrollmentState}},

@{Label="User Assigned";Expression={$_.UserPrincipalName}}

)

Write-Host "\n========================================`n" -ForegroundColor Cyan`

# Export to CSV if path specified

if ($ExportPath)

{

try

{

$AllUnassignedDevices | Export-Csv -Path $ExportPath -NoTypeInformation -Encoding UTF8

Write-Host "[✓] Results exported to: $ExportPath" -ForegroundColor Green

}

catch

{

Write-Warning "Failed to export to CSV: $_"

}

}

}

}

catch

{

Write-Error "\nScript failed: $($_.Exception.Message)"`

exit 1

}

finally

{

# Disconnect from Microsoft Graph

try

{

### Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null

Write-Host "\nDisconnected from Microsoft Graph" -ForegroundColor Gray`

}

catch

{

}

}

Write-Host "\nScript completed successfully!" -ForegroundColor Green`

Note so in theory it's upset about one of the squiggly brackets between

Write-Warning "Failed to export to CSV: $_"

statement and the Catch statement.

Just everything seems matched up right.

reddit.com
u/jriker2 — 18 hours ago