Back up (or restore) Jamf Pro objects with PowerShell

Back up (or restore) Jamf Pro objects with PowerShell

I recently started working a lot with Jamf Pro and have been enjoying it quite a bit.
Coming from a heavy background in Intune, there is a lot to learn an understand with a new MDM. This post is about a tool I wrote to help myself and hopefully others with a similar situation.

If you’re tinkering with any system, ideally, you’d take a snapshot before making changes—so why not your Jamf configs? I’ve messed around with clunky backup methods before, but they left me hoping for more functionality. Restores were a pain, everything dumped back at once, names clashed, and versioning was a guessing game. Then I caught "Back to the Future: Backing Up All (most) of The Objects in Jamf Pro" from JNUC 2023, and it flipped a switch. I had to build something better for myself.

Enter PsJamfBackupRestore, a PowerShell tool set that backs up and restores your Jamf Pro setup with finesse. While new and in a alpha state, it's got:

  • Selective backups—grab just Computers, Scripts, Policies, or whatever you pick.
  • Support for tons of config types, from Profiles to Prestages.
  • Authentication your way: Username/Password or OAuth Client ID/Secret.
  • Clean backups to a JAMF_Backup folder, organized by resource.
  • Token smarts—auto-renewal and cleanup included.

Usage

Kick things off by cloning the repo:

git clone https://github.com/jorgeasaurus/PsJamfBackupRestore.git
Set-Location PsJamfBackupRestore

Tweaking config.ps1 with your Jamf Pro details—URL, credentials,etc:

[hashtable]$script:Config = @{
    BaseUrl      = "https://example.jamfcloud.com"
    Username     = "username" # Leave empty if using API credentials
    Password     = "password" # Leave empty if using API credentials
    #clientId     = "your-client-id" # Fill if using API credentials
    #clientSecret = "your-client-secret"# Fill if using API credentials
    DataFolder   = Join-Path (Get-Location) "JAMF_Backup"
    ApiVersion   = "classic"           # Use 'v1','v2' or 'classic'
    Token        = $null
}

Load the configs and functions:

. (Join-Path (Get-Location) "config.ps1")
. (Join-Path (Get-Location) "JamfBackupRestoreFunctions.ps1")

Then dive in. Here’s the rundown:

Request a token from Jamf

$tokenParams = @{
    Username    = $script:Config.Username
    Password    = $script:Config.Password
    JamfProUrl  = $script:Config.JamfProUrl
}
$script:Config.Token = Get-JamfToken @tokenParams

Backup Everything: Snag all Scripts (or any resource) and nuke old backups (optional):

Download-JamfObjects -Resource "scripts" -ClearExports

Backup One Thing: Grab a specific config by ID:

Download-JamfObject -ID "3" -Resource "osxconfigurationprofiles"

Restore a Single Object: Push an updated object back:

Upload-JamfObject -Token $Config.Token -FilePath "JAMF_Backup/policies/3_Google_Chrome.xml" -Resource "policies" -Id "3" -Update

Create Something New: Add a fresh category:

Upload-JamfObject -Token $Config.Token -FilePath "JAMF_Backup/categories/Security.xml" -Resource "categories"

Restore a Batch: Bring back all Policies:

Upload-JamfObjects -Resource "policies"

Clean Up: Revoke your token when you’re done:

Invalidate-JamfToken -Token $Config.Token

Check the repo’s README for the full playbook.


How It Works

This script chats with the Jamf API, juggling Classic (/JSSResource) and v1 (/api/v1/) endpoints—v2’s wired up too, just waiting for Jamf to fully support it. You set your creds in $Config (Username/Password or OAuth), and it pulls down resources as JSON or XML, depending on the API. Scripts get a bonus .sh file alongside their metadata. Everything lands in JAMF_Backup, split by type—think policies/1_Policy_Name.xml or scripts/2_Script_Name.sh. Tokens renew automatically, and you can zap them when you’re done for security.


What’s Next?

  • I hope to add more supported api endpoints.
  • Possibly a console gui for more interactive use.
  • Functionality to post the exports in a repository.

Anyway, any feedback is welcome, pull requests also encouraged.

>Jorgesaurus

Subscribe to > Jorgeasaurus

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe