Initial Version
This commit is contained in:
commit
740994ae40
4 changed files with 217 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.html
|
132
AppleBusinessManager.psd1
Normal file
132
AppleBusinessManager.psd1
Normal file
|
@ -0,0 +1,132 @@
|
|||
#
|
||||
# Module manifest for module 'ABMPS'
|
||||
#
|
||||
# Generated by: Liam Steckler
|
||||
#
|
||||
# Generated on: 6/11/2025
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'AppleBusinessManager.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.0'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'ba7191aa-8343-45d4-941b-52ddc74d7cc7'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Liam Steckler'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Unknown'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = '(c) Liam Steckler. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
# Description = ''
|
||||
|
||||
# Minimum version of the PowerShell engine required by this module
|
||||
PowerShellVersion = '7.0.0'
|
||||
|
||||
# Name of the PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# ClrVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
# RequiredModules = @()
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
AliasesToExport = '*'
|
||||
|
||||
# DSC resources to export from this module
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
# Tags = @()
|
||||
|
||||
# A URL to the license for this module.
|
||||
# LicenseUri = ''
|
||||
|
||||
# A URL to the main website for this project.
|
||||
# ProjectUri = ''
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
# Prerelease string of this module
|
||||
# Prerelease = ''
|
||||
|
||||
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
|
||||
# RequireLicenseAcceptance = $false
|
||||
|
||||
# External dependent modules of this module
|
||||
# ExternalModuleDependencies = @()
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
|
81
AppleBusinessManager.psm1
Normal file
81
AppleBusinessManager.psm1
Normal file
|
@ -0,0 +1,81 @@
|
|||
#Requires -Version 7.0
|
||||
#Requires -Module jwtPS
|
||||
function Connect-AppleBusinessManager {
|
||||
if (-not $Env:AppleBusinessManagerClientId -or -not $Env:AppleBusinessManagerPrivateKeyId -or -not $Env:AppleBusinessManagerPrivateKey) {
|
||||
throw "Client ID, Private Key ID and Private Key environment variables were not set for Apple Business Manager"
|
||||
}
|
||||
$Script:ClientId = $Env:AppleBusinessManagerClientId
|
||||
$Script:PrivateKey = $Env:AppleBusinessManagerPrivateKey
|
||||
$Script:PrivateKeyId = $Env:AppleBusinessManagerPrivateKeyId
|
||||
|
||||
$Header = @{
|
||||
'kid' = $Script:PrivateKeyId
|
||||
}
|
||||
|
||||
$Payload = @{
|
||||
aud = "https://account.apple.com/auth/oauth2/v2/token"
|
||||
iss = $Script:ClientId
|
||||
sub = $Script:ClientId
|
||||
iat = ([System.DateTimeOffset]::Now).ToUnixTimeSeconds()
|
||||
exp = ([System.DateTimeOffset]::Now.AddMinutes(15)).ToUnixTimeSeconds()
|
||||
jti = [guid]::NewGuid()
|
||||
}
|
||||
|
||||
$Hashing = [jwtTypes+encryption]::SHA256
|
||||
$Signature = [jwtTypes+algorithm]::ECDsa
|
||||
$Algorithm = [jwtTypes+cryptographyType]::new($Signature, $Hashing)
|
||||
$JWT = New-JWT -Payload $Payload -Algorithm $Algorithm -Secret $Script:PrivateKey -Header $Header
|
||||
Write-Verbose $JWT
|
||||
|
||||
$Script:Body = @{
|
||||
'grant_type' = 'client_credentials'
|
||||
'client_id' = $Script:ClientId
|
||||
'client_assertion' = $JWT
|
||||
'client_assertion_type' = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
|
||||
'scope' = 'business.api'
|
||||
}
|
||||
|
||||
$Script:AuthResponse = Invoke-RestMethod -Method Post -Uri 'https://account.apple.com/auth/oauth2/token' -Body $Script:Body -SkipHttpErrorCheck
|
||||
if ($Script:AuthResponse.error) {
|
||||
throw $Script:AuthResponse.Error
|
||||
}
|
||||
$Script:ExpiresAt = (Get-Date).AddSeconds($Script:AuthResponse.expires_in)
|
||||
}
|
||||
|
||||
function Get-AppleBusinessManagerBearerToken {
|
||||
if (-not $Script:AuthResponse) {
|
||||
try {
|
||||
Connect-AppleBusinessManager
|
||||
}
|
||||
catch {
|
||||
throw "Authorization has not been completed, use Connect-AppleBusinessManager first."
|
||||
}
|
||||
}
|
||||
if ((Get-Date).AddMinutes(1) -ge $Script:ExpiresAt) {
|
||||
# Access token is approaching expiration, get a new access token
|
||||
Connect-AppleBusinessManager
|
||||
}
|
||||
|
||||
return ($Script:AuthResponse.access_token | ConvertTo-SecureString -AsPlainText -Force)
|
||||
}
|
||||
|
||||
function Invoke-AppleBusinessManagerPagedApiRequest {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)][uri] $Uri
|
||||
)
|
||||
$Results = New-Object System.Collections.ArrayList
|
||||
while ($Uri) {
|
||||
$Result = Invoke-RestMethod $Uri -Authentication Bearer -Token (Get-AppleBusinessManagerBearerToken) -ErrorAction Stop
|
||||
$Uri = $Result.links.next
|
||||
$Results.AddRange($Result.data) | Out-Null
|
||||
}
|
||||
return $Results
|
||||
}
|
||||
|
||||
function Get-AppleBusinessManagerOrgDevices {
|
||||
return Invoke-AppleBusinessManagerPagedApiRequest -Uri "https://api-business.apple.com/v1/orgDevices"
|
||||
}
|
||||
|
||||
function Get-AppleBusinessManagerMdmServers {
|
||||
return Invoke-AppleBusinessManagerPagedApiRequest -Uri "https://api-business.apple.com/v1/mdmServers"
|
||||
}
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Apple Business Manager API Module for PowerShell
|
||||
To use this module, you'll need to convert the private key from Apple to a .NET friendly format:
|
||||
```openssl pkcs8 -topk8 -inform PEM -outform PEM -in [path to your key from Apple] -out [path to where you want to save the converted key] -nocrypt```
|
Loading…
Add table
Add a link
Reference in a new issue