---
title: "Upload a PowerShell Script to Intune (With PowerShell) From Scratch"
description: "Automate deploying PowerShell scripts to Intune devices with Azure app registration, Graph API, and more in this step-by-step tutorial."
canonical: "https://adamtheautomator.com/intune-powershell-script-upload/"
---

# Upload a PowerShell Script to Intune (With PowerShell) From Scratch

> Automate deploying PowerShell scripts to Intune devices with Azure app registration, Graph API, and more in this step-by-step tutorial.

Source: https://adamtheautomator.com/intune-powershell-script-upload/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Upload a PowerShell Script to Intune (With PowerShell) From Scratch](https://adamtheautomator.com/wp-content/uploads/2024/05/2024-05-16_15-23-27.jpg)

# Upload a PowerShell Script to Intune (With PowerShell) From Scratch

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)22 May 20243 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[PowerShell](/tag/powershell/)

Table of Contents

*   [Step 1: Install Required Modules and Authenticate to Azure](#step-1-install-required-modules-and-authenticate-to-azure)
*   [Step 2: Define Required Resource Access](#step-2-define-required-resource-access)
*   [Step 3: Create the App Registration](#step-3-create-the-app-registration)
*   [Step 4: Generate a Client Secret](#step-4-generate-a-client-secret)
*   [Step 5: Obtain a Microsoft Graph API Token](#step-5-obtain-a-microsoft-graph-api-token)
*   [Step 6: Prepare the Script Content](#step-6-prepare-the-script-content)
*   [Step 7: Create the HTTP Body for the REST Call](#step-7-create-the-http-body-for-the-rest-call)
*   [Step 8: Make the API Call](#step-8-make-the-api-call)

If you have Intune at your organization with some PowerShell scripts you need to run on remote machines, this tutorial is for you.

Let’s tackle a project where we’ll cover everything from automating creating an Azure app registration, generating a client secret, obtaining a Microsoft Graph API token, and using that token to deploy a device management script. It might sound like a lot, but trust me, I’ll guide you step-by-step!

## **Step 1: Install Required Modules and Authenticate to Azure**

First things first, we need to install the required PowerShell modules and authenticate to Azure. This is a crucial step because without the right modules and proper authentication, nothing else will work. Open up your PowerShell console and run the following commands:

```
# Install necessary Azure PowerShell modules
Install-Module 'Az.Resources', 'Az.Accounts'

# Authenticate to Azure
Connect-AzAccount
```

When you run these commands, you’ll be prompted to log into your Azure account. Follow the prompts, enter your credentials, and you’ll be all set.

## **Step 2: Define Required Resource Access**

Next, we need to define the resource access that our app registration will need. Specifically, we need to access the Microsoft Graph API with certain permissions. We’ll define these permissions in a PowerShell hash table. This table includes the ResourceAppId, which is the ID for Microsoft Graph, and the ResourceAccess, which specifies the permissions our app will need. Here’s what that looks like:

```
# Define required resource access
$requiredResourceAccess = @(
    @{
        ResourceAppId  = "00000003-0000-0000-c000-000000000000"  # Microsoft Graph API ID
        ResourceAccess = @(
            @{
                Id   = "9241abd9-d0e6-425a-bd4f-47ba86e767a4"     # DeviceManagementConfiguration.ReadWrite.All permission ID
                Type = "Role"
            }
        )
    }
)
```

## **Step 3: Create the App Registration**

Now that we’ve defined the required resource access, let’s create the app registration. This registration essentially tells Azure AD that we want to create a new application with the specified permissions. Run the following command:

```
$app = New-AzADApplication -DisplayName DeviceManagementScriptApp -RequiredResourceAccess $requiredResourceAccess
```

This command will register a new application in Azure AD with the specified permissions. The `**$app**` variable now holds the details of the newly created app.

## **Step 4: Generate a Client Secret**

Next, we need to generate a client secret for our app registration. Think of this as a password for your app that allows it to authenticate and access resources securely. Here’s how you do it:

```
$secret = New-AzADAppCredential -ObjectId $app.Id
```

This command creates a client secret, which we’ll use later when making API calls. It’s crucial to store this secret securely because it acts like a password for your app.

## **Step 5: Obtain a Microsoft Graph API Token**

Now, we need to create a function to get a Microsoft Graph API token using our app’s credentials. Tokens are essential for proving our identity when calling the API. The function below will help us obtain this token:

```
function getGraphApiToken {
    param (
        [string]$TenantId,
        [string]$ClientId,
        [string]$ClientSecret
    )

    $body = @{
        grant_type    = "client_credentials"
        scope         = "https://graph.microsoft.com/.default"
        client_id     = $ClientId
        client_secret = $ClientSecret
    }

    $tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
    $tokenResponse.access_token
}

# Example usage
$TenantId = "<Your-Tenant-ID>"
$ClientId = $app.ApplicationId
$ClientSecret = $secret.SecretText
$token = getGraphApiToken -TenantId $TenantId -ClientId $ClientId -ClientSecret $ClientSecret
```

This function sends a request to Azure AD’s token endpoint to get an access token. The `**Invoke-RestMethod**` command is key here as it handles the HTTP POST request and returns the access token we need for further API calls.

## **Step 6: Prepare the Script Content**

Let’s move on to preparing the PowerShell script content we want to deploy. This script will be encoded in base64 format because the Graph API expects the script content in this format. Here’s how you do it:

```
# Define the script content
$someScriptContent = @'
## This is some PowerShell script
Test-Path C:
'@

# Encode the script content to base64
$base64ScriptContent = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($someScriptContent))
```

We first define our script content, then convert it to a base64-encoded string, ensuring it’s properly formatted for transmission via the Graph API.

## **Step 7: Create the HTTP Body for the REST Call**

Next, let’s prepare the HTTP body for the REST call to the Graph API. This includes setting up the headers and body for our request. The headers will contain the authorization token, and the body will include details about the script, such as its content and language:

```
# Prepare the headers with the token
$headers = @{
    Authorization  = "Bearer $token"
    'Content-Type' = 'application/json'
}

# Create the HTTP body for the REST call
$body = @{
    "@odata.type"           = "#microsoft.graph.deviceManagementScript"
    "scriptContent"         = $base64ScriptContent
    "scriptLanguage"        = "PowerShell"
    "displayName"           = "Example Script"
    "description"           = "This is an example script."
    "runAsUser"             = "system"
    "runAs32Bit"            = $false
    "enforceSignatureCheck" = $false
}
```

## **Step 8: Make the API Call**

Finally, let’s set up the parameters for the REST API call and execute it. This step involves making a POST request to the Graph API endpoint to deploy our device management script.

```
powershellCopy code
# Set up the params for the REST API call
$irmParams = @{
    Uri                = 'https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts'
    Method             = 'POST'
    Headers            = $headers
    StatusCodeVariable = 'respStatus'
    SkipHttpErrorCheck = $true
    Body               = ($body | ConvertTo-Json)
}

# Make the API call
$response = Invoke-RestMethod @irmParams

# Handle any errors
if ($respStatus -ne 201) {
    throw $response.error.message
} else {
    Write-Output "Script deployed successfully!"
}
```

This code block sets up the parameters for the `**Invoke-RestMethod**` command, which sends our script content to the specified Graph API endpoint. The `**StatusCodeVariable**` captures the response status code to check if our request was successful. If everything goes well, you’ll see “Script deployed successfully!” printed out.

And there you have it! You’ve successfully automated the process of creating an Azure app registration, generating a client secret, obtaining a Microsoft Graph API token, and deploying a device management script. This powerful workflow enables you to manage Azure resources efficiently and securely. Feel free to customize the script and parameters to suit your specific needs. Happy scripting!

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fintune-powershell-script-upload%2F&text=Upload%20a%20PowerShell%20Script%20to%20Intune%20\(With%20PowerShell\)%20From%20Scratch)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fintune-powershell-script-upload%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fintune-powershell-script-upload%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/publisher/2e05d9c85b2b81feb24af1f04a889143/3eab14af9dabf46fbd333914ce6ccf46f84117d2394d3e7218c186cd249bb7e2.webp)

### [PowerShell or Power Automate: Stop Automation Mistakes](/powershell-vs-power-automate/)

Score six factors to choose between PowerShell and Power Automate: target system, complexity, data volume, team skills, cost, governance.

![](https://adamtheautomator.com/wp-content/uploads/2026/06/26995-troubleshoot-dns-issues-powershell-codex.webp)

### [Troubleshoot DNS Issues with PowerShell](/troubleshoot-dns-issues-powershell/)

Troubleshoot DNS issues with PowerShell by testing name resolution, DNS client settings, cache entries, and network connectivity in a repeatable workflow.

![](https://adamtheautomator.com/wp-content/uploads/2025/10/image_2025-10-24_095322075.png)

### [Migrating from PowerShell 6 to 7.5: Breaking Changes/New Features](/migrating-powershell-6-to-7-5/)

Migrate from PowerShell Core 6 to 7.5: breaking changes, features, and testing tips.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
