Geräte-Tab: Suche, Detail-Panel und Aktionen
Neuer Haupttab "Geräte" mit Geräteliste (filterbar nach OS/Compliance), Detail-Panel mit vollständigen Gerätedaten und Aktions-Buttons: Sync, Neustart, Sperren, Diagnose, BitLocker-Rotation, Retire. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+113
@@ -70,6 +70,18 @@ function Invoke-ApiHandler {
|
||||
return Get-UserMemberOfEndpoint -UserId $matches[1]
|
||||
}
|
||||
|
||||
if ($Method -eq "GET" -and $Path -eq "/api/devices") {
|
||||
return Search-DevicesEndpoint -Query $Query
|
||||
}
|
||||
|
||||
if ($Method -eq "GET" -and $Path -match "^/api/devices/([^/]+)$") {
|
||||
return Get-DeviceEndpoint -DeviceId $matches[1]
|
||||
}
|
||||
|
||||
if ($Method -eq "POST" -and $Path -match "^/api/devices/([^/]+)/action$") {
|
||||
return Invoke-DeviceActionEndpoint -DeviceId $matches[1] -Body $Body
|
||||
}
|
||||
|
||||
if ($Method -eq "GET" -and $Path -match "^/api/apps/([^/]+)/details$") {
|
||||
return Get-AppDetailsEndpoint -AppId $matches[1]
|
||||
}
|
||||
@@ -1520,6 +1532,107 @@ function Get-UserMemberOfEndpoint {
|
||||
return @{ groups = $groups; count = $groups.Count }
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# Devices
|
||||
# ============================================================
|
||||
|
||||
function Search-DevicesEndpoint {
|
||||
param($Query)
|
||||
$err = Test-Connected
|
||||
if ($err) { return $err }
|
||||
|
||||
$q = [string]$Query.q
|
||||
$os = [string]$Query.os
|
||||
$compliance = [string]$Query.compliance
|
||||
$top = 100
|
||||
|
||||
$filters = @()
|
||||
if ($q -and $q.Length -ge 2) {
|
||||
$qEnc = [uri]::EscapeDataString($q)
|
||||
$filters += "(startswith(deviceName,'$q') or startswith(userDisplayName,'$q') or startswith(serialNumber,'$q'))"
|
||||
}
|
||||
if ($os) { $filters += "operatingSystem eq '$os'" }
|
||||
if ($compliance) { $filters += "complianceState eq '$compliance'" }
|
||||
|
||||
$filterStr = if ($filters.Count -gt 0) { '$filter=' + [uri]::EscapeDataString(($filters -join ' and ')) + '&' } else { '' }
|
||||
$select = 'id,deviceName,userDisplayName,userPrincipalName,operatingSystem,osVersion,complianceState,lastSyncDateTime,managementState,serialNumber,model,manufacturer,enrolledDateTime'
|
||||
$uri = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?${filterStr}`$select=$select&`$top=$top&`$orderby=deviceName"
|
||||
|
||||
$items = @()
|
||||
$resp = Invoke-MgGraphRequestRetry -Uri $uri -Method GET
|
||||
foreach ($d in $resp.value) {
|
||||
$items += [pscustomobject]@{
|
||||
Id = $d.id
|
||||
DeviceName = $d.deviceName
|
||||
UserDisplayName = $d.userDisplayName
|
||||
UserPrincipalName= $d.userPrincipalName
|
||||
OS = $d.operatingSystem
|
||||
OSVersion = $d.osVersion
|
||||
ComplianceState = $d.complianceState
|
||||
LastSync = $d.lastSyncDateTime
|
||||
ManagementState = $d.managementState
|
||||
SerialNumber = $d.serialNumber
|
||||
Model = $d.model
|
||||
Manufacturer = $d.manufacturer
|
||||
EnrolledDateTime = $d.enrolledDateTime
|
||||
}
|
||||
}
|
||||
return @{ items = $items; count = $items.Count }
|
||||
}
|
||||
|
||||
function Get-DeviceEndpoint {
|
||||
param($DeviceId)
|
||||
$err = Test-Connected
|
||||
if ($err) { return $err }
|
||||
|
||||
$select = 'id,deviceName,userDisplayName,userPrincipalName,operatingSystem,osVersion,complianceState,lastSyncDateTime,managementState,serialNumber,model,manufacturer,enrolledDateTime,imei,wiFiMacAddress,azureADDeviceId,joinType,deviceEnrollmentType,managedDeviceOwnerType,totalStorageSpaceInBytes,freeStorageSpaceInBytes'
|
||||
$d = Invoke-MgGraphRequestRetry -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$DeviceId`?`$select=$select" -Method GET
|
||||
|
||||
$totalGB = if ($d.totalStorageSpaceInBytes) { [math]::Round($d.totalStorageSpaceInBytes / 1GB, 1) } else { $null }
|
||||
$freeGB = if ($d.freeStorageSpaceInBytes) { [math]::Round($d.freeStorageSpaceInBytes / 1GB, 1) } else { $null }
|
||||
|
||||
return @{
|
||||
Id = $d.id
|
||||
DeviceName = $d.deviceName
|
||||
UserDisplayName = $d.userDisplayName
|
||||
UserPrincipalName= $d.userPrincipalName
|
||||
OS = $d.operatingSystem
|
||||
OSVersion = $d.osVersion
|
||||
ComplianceState = $d.complianceState
|
||||
LastSync = $d.lastSyncDateTime
|
||||
ManagementState = $d.managementState
|
||||
SerialNumber = $d.serialNumber
|
||||
Model = $d.model
|
||||
Manufacturer = $d.manufacturer
|
||||
EnrolledDateTime = $d.enrolledDateTime
|
||||
Imei = $d.imei
|
||||
WiFiMac = $d.wiFiMacAddress
|
||||
AzureADDeviceId = $d.azureADDeviceId
|
||||
JoinType = $d.joinType
|
||||
EnrollmentType = $d.deviceEnrollmentType
|
||||
OwnerType = $d.managedDeviceOwnerType
|
||||
TotalStorageGB = $totalGB
|
||||
FreeStorageGB = $freeGB
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-DeviceActionEndpoint {
|
||||
param($DeviceId, $Body)
|
||||
$err = Test-Connected
|
||||
if ($err) { return $err }
|
||||
|
||||
$action = [string]$Body.action
|
||||
$allowed = @('syncDevice','rebootNow','remoteLock','collectDiagnostics','rotateBitLockerKeys','retire')
|
||||
if ($action -notin $allowed) {
|
||||
return @{ statusCode = 400; error = "Unbekannte Aktion: $action" }
|
||||
}
|
||||
|
||||
$uri = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$DeviceId/$action"
|
||||
$bodyJson = '{}'
|
||||
Invoke-MgGraphRequestRetry -Uri $uri -Method POST -Body $bodyJson -ContentType 'application/json' | Out-Null
|
||||
return @{ success = $true; action = $action }
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# Apps
|
||||
# ============================================================
|
||||
|
||||
Reference in New Issue
Block a user