Functions/Public/Get-JCRGlobalVars.ps1
function Get-JCRGlobalVars { [CmdletBinding()] param ( [Parameter(HelpMessage = "Force update all cached users, systems, associations, radius group members")] [switch] $force, [Parameter(HelpMessage = "Skips the user to system association cache, which may take a long time on larger organizations")] [switch] $skipAssociation, [Parameter(HelpMessage = "Updates the system to user association cache manually using the graph api")] [switch] $associateManually, [Parameter(HelpMessage = "Updates just a single user's associations manually using the graph api")] [System.String] $associationUsername ) begin { Write-Verbose 'Verifying JCAPI Key' if ($JCAPIKEY.length -ne 40) { Connect-JCOnline -force } # ensure the data directory exists to cache the json files: if (-not (Test-Path "$JCRScriptRoot/data")) { Write-Host "[status] Creating Data Directory" New-Item -ItemType Directory -Path "$JCRScriptRoot/data" } if (-Not $global:JCRConfig) { $global:JCRConfig = Get-JCRConfig } # get settings file if ($IsMacOS) { try { $lastUpdateTimeSpan = New-TimeSpan -Start $($global:JCRConfig.lastUpdate.value) -End (Get-Date) } catch { Write-Host "[status] lastUpdate value is null, updating global variables" $update = $true $updateAssociation = $true Set-JCRConfig -lastUpdate (Get-Date) } } if ($ifWindows) { try { $lastUpdateTimeSpan = New-TimeSpan -Start $($global:JCRConfig.lastUpdate.value) -End (Get-Date) } catch { Write-Host "[status] lastUpdate value is null, updating global variables" $update = $true $updateAssociation = $true Set-JCRConfig -lastUpdate (Get-Date) } } if ($lastUpdateTimeSpan.TotalHours -gt 24) { $update = $true $updateAssociation = $true } else { $update = $false $updateAssociation = $false } if ($force) { $update = $true switch ($skipAssociation) { $true { $updateAssociation = $false } $false { $updateAssociation = $true } } switch ($associateManually) { $true { $updateAssociation = $false $setAssociations = $true } $false { $updateAssociation = $true $setAssociations = $false } } } # also validate that the data files are non-null, if they are, force update] $requiredHashFiles = @('radiusMembers.json', 'systemHash.json', 'userHash.json', 'certHash.json') foreach ($file in $requiredHashFiles) { if (Test-Path -Path "$JCRScriptRoot/data/$file") { $fileContents = Get-Content "$JCRScriptRoot/data/$file" } else { Write-Host "[status] $JCRScriptRoot/data/$file file does not exist, updating global variables" $update = $true } # if the file is null force update if ([string]::IsNullOrEmpty($fileContents)) { Write-Host "[status] $JCRScriptRoot/data/$file file is null, updating global variables" $update = $true } } $requiredAssociationHashFiles = @('associationHash.json') foreach ($file in $requiredAssociationHashFiles) { if (Test-Path -Path "$JCRScriptRoot/data/$file") { $fileContents = Get-Content "$JCRScriptRoot/data/$file" switch ($skipAssociation) { $true { # Write-Host "[status] $JCRScriptRoot/data/$file will be skipped" $updateAssociation = $false } } } else { Write-Host "[status] $JCRScriptRoot/data/$file file does not exist, updating global variables" $update = $true $updateAssociation = $true } # if the file is null force update if ([string]::IsNullOrEmpty($fileContents)) { Write-Host "[status] $JCRScriptRoot/data/$file file is null, updating global variables" $update = $true $updateAssociation = $true } else { switch ($skipAssociation) { $true { # Write-Host "[status] $JCRScriptRoot/data/$file will be skipped" $updateAssociation = $false } } } } } process { switch ($update) { $true { # update the global variables $systems = Get-DynamicHash -Object System -returnProperties hostname, os, osFamily, version, fde, lastContact $users = Get-DynamicHash -Object User -returnProperties email, employeeIdentifier, department, suspended, location, Addresses, manager, sudo, Displayname, username, systemUsername # $users | ForEach-Object { $_ | Add-Member -name "userId" -value $_ -Type NoteProperty -force } # Get Radius membership list: $radiusMembers = Get-JcSdkUserGroupMember -GroupId $global:JCRConfig.userGroup.value # add the username to the membership hash $radiusMemberList = New-Object System.Collections.ArrayList foreach ($member in $radiusMembers) { $radiusMemberList.Add( [PSCustomObject]@{ 'userID' = $member.toID 'username' = $users[$member.toID].username } ) | Out-Null } if ($updateAssociation) { # get the latest report, generate a new report if it's been more than 10 mins $reportContent = Get-LatestUserToDeviceReport -minutes 10 # create the hashtable: $userAssociationList = New-Object System.Collections.Hashtable foreach ($item in $reportContent) { if ($item.user_object_id -And $item.resource_object_id) { if (-not $userAssociationList[$item.user_object_id]) { $userAssociationList.add( $item.user_object_id, @{ 'systemAssociations' = @($item | Select-Object -Property @{Name = 'systemId'; Expression = { $_.resource_object_id } }, hostname, @{Name = 'osFamily'; Expression = { $_.device_os } }); 'userData' = @($item | Select-Object -Property email, username) }) | Out-Null } else { $userAssociationList[$item.user_object_id].systemAssociations += @($item | Select-Object -Property @{Name = 'systemId'; Expression = { $_.resource_object_id } }, hostname, @{Name = 'osFamily'; Expression = { $_.device_os } }) } } } # write out the association hash $userAssociationList | ConvertTo-Json -Depth 10 | Out-File "$JCRScriptRoot/data/associationHash.json" } else { $userAssociationList = Get-Content -Raw -Path "$JCRScriptRoot/data/associationHash.json" | ConvertFrom-Json -Depth 6 -AsHashtable } if ($setAssociations) { # create the hashtable: $userAssociationList = New-Object System.Collections.Hashtable foreach ($user in $radiusMemberList) { $userSystemMembership = Get-JcSdkUserTraverseSystem -UserId $user.userID if ($userSystemMembership) { $userAssociationList.add( $user.userID, @{ 'systemAssociations' = @($userSystemMembership | Select-Object -Property @{Name = 'systemId'; Expression = { $_.id } }, @{Name = 'hostname'; Expression = { $systems[$_.id].hostname } }, @{Name = 'osFamily'; Expression = { $osFamilyValue = $systems[$_.id].osFamily if ($osFamilyValue -eq 'darwin') { "macOS" } elseif ($osFamilyValue -eq 'Windows') { "Windows" } else { $osFamilyValue } } }); 'userData' = @($user | Select-Object -Property @{Name = 'email'; Expression = { $users[$user.userID].email } }, @{Name = 'username'; Expression = { $users[$user.userID].username } }) }) | Out-Null } } # write out the association hash $userAssociationList | ConvertTo-Json -Depth 10 | Out-File "$JCRScriptRoot/data/associationHash.json" } if ($associationUsername) { $userAssociationList = Get-Content -Raw -Path "$JCRScriptRoot/data/associationHash.json" | ConvertFrom-Json -Depth 6 -AsHashtable $matchedUser = $radiusMemberList | Where-Object { $_.username -eq $associationUsername } if (-Not $matchedUser) { Write-Warning "user not found" } else { $userSystemMembership = Get-JcSdkUserTraverseSystem -UserId $matchedUser.userID if ($userSystemMembership) { # check if the user exists if ($userAssociationList[$matchedUser.userID]) { $userAssociationList[$matchedUser.userID].'systemAssociations' = @($userSystemMembership | Select-Object -Property @{Name = 'systemId'; Expression = { $_.id } }, @{Name = 'hostname'; Expression = { $systems[$_.id].hostname } }, @{Name = 'osFamily'; Expression = { $osFamilyValue = $systems[$_.id].osFamily if ($osFamilyValue -eq 'darwin') { "macOS" } elseif ($osFamilyValue -eq 'Windows') { "Windows" } else { $osFamilyValue } } }); } else { Write-Warning "user not found in association list" $userAssociationList.add( $matchedUser.UserId, @{ 'systemAssociations' = @($userSystemMembership | Select-Object -Property @{Name = 'systemId'; Expression = { $_.id } }, @{Name = 'hostname'; Expression = { $systems[$_.id].hostname } }, @{Name = 'osFamily'; Expression = { $osFamilyValue = $systems[$_.id].osFamily if ($osFamilyValue -eq 'darwin') { "macOS" } elseif ($osFamilyValue -eq 'Windows') { "Windows" } else { $osFamilyValue } } }); 'userData' = @($matchedUser | Select-Object -Property @{Name = 'email'; Expression = { $users[$user.userID].email } }, @{Name = 'username'; Expression = { $users[$matchedUser.userID].username } }) }) | Out-Null } } # } # write out the association hash $userAssociationList | ConvertTo-Json -Depth 10 | Out-File "$JCRScriptRoot/data/associationHash.json" } # update certHash in parallel: $certHash = Get-CertHash # finally write out the data to file: $users | ConvertTo-Json -Depth 100 -Compress | Out-File "$JCRScriptRoot/data/userHash.json" $systems | ConvertTo-Json -Depth 10 | Out-File "$JCRScriptRoot/data/systemHash.json" $radiusMemberList | ConvertTo-Json | Out-File "$JCRScriptRoot/data/radiusMembers.json" $certHash | ConvertTo-Json | Out-File "$JCRScriptRoot/data/certHash.json" } $false { # write-host "It's been $($lastUpdateTimespan.hours) hours since we last pulled user, system and association data, no need to update" $userAssociationList = Get-Content -Raw -Path "$JCRScriptRoot/data/associationHash.json" | ConvertFrom-Json -Depth 6 -AsHashtable } } } end { switch ($update) { $true { # set global vars $Global:JCRUsers = $users $Global:JCRSystems = $systems $Global:JCRAssociations = $userAssociationList [array]$Global:JCRRadiusMembers = $radiusMemberList $Global:JCRCertHash = $certHash # update the settings date Set-JCRConfig -lastUpdate (Get-Date) # update users.json Update-JCRUsersJson } $false { # set global vars from local cache $Global:JCRUsers = Get-Content -Path "$JCRScriptRoot/data/userHash.json" | ConvertFrom-Json -AsHashtable $Global:JCRSystems = Get-Content -Path "$JCRScriptRoot/data/systemHash.json" | ConvertFrom-Json -AsHashtable $Global:JCRAssociations = Get-Content -Path "$JCRScriptRoot/data/associationHash.json" | ConvertFrom-Json -AsHashtable [array]$Global:JCRRadiusMembers = Get-Content -Path "$JCRScriptRoot/data/radiusMembers.json" | ConvertFrom-Json -AsHashtable $Global:JCRCertHash = Get-Content -Path "$JCRScriptRoot/data/certHash.json" | ConvertFrom-Json -AsHashtable # update users.json Update-JCRUsersJson } } } } |