v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}

Shankar Subramanian
Bindusar Kushwaha
3
890
2024-04-28T06:39:00Z
2024-04-28T06:41:00Z
1
2001
11410
Microsoft
95
26
13385
16.00

Clean
Clean
false

false
false
false

EN-US
X-NONE
HI

/* Style Definitions */
table.MsoNormalTable
{mso-style-name:”Table Normal”;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:””;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin-top:0cm;
mso-para-margin-right:0cm;
mso-para-margin-bottom:8.0pt;
mso-para-margin-left:0cm;
line-height:107%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:”Aptos”,sans-serif;
mso-ascii-font-family:Aptos;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Aptos;
mso-hansi-theme-font:minor-latin;
mso-font-kerning:1.0pt;
mso-ligatures:standardcontextual;
mso-ansi-language:EN-US;
mso-fareast-language:EN-US;
mso-bidi-language:AR-SA;}
table.MsoTableGrid
{mso-style-name:”Table Grid”;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-priority:39;
mso-style-unhide:no;
border:solid windowtext 1.0pt;
mso-border-alt:solid windowtext .5pt;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-border-insideh:.5pt solid windowtext;
mso-border-insidev:.5pt solid windowtext;
mso-para-margin:0cm;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:”Aptos”,sans-serif;
mso-ascii-font-family:Aptos;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Aptos;
mso-hansi-theme-font:minor-latin;
mso-font-kerning:1.0pt;
mso-ligatures:standardcontextual;
mso-ansi-language:EN-US;
mso-fareast-language:EN-US;
mso-bidi-language:AR-SA;}

How to Register an Application in Microsoft
Entra ID and Grant Permissions to SharePoint Site

A Step-by-Step Guide

Introduction

Hello Everyone, I am Shankar Subramaniun, In this document I will guide you through the
process of registering an application in Microsoft Entra ID and granting it
permissions to access a specific SharePoint site using Microsoft Graph API.
This is useful for scenarios where you need to authenticate your application
and perform operations on a SharePoint site programmatically.

Prerequisites

·      
A Microsoft 365 subscription
with SharePoint Online.

·      
An Azure AD tenant where you
can register an application.

·      
A SharePoint site that you want
to grant permissions to.

·      
PowerShell 7 or higher with Microsoft.Graph module installed.

Steps

Step 1: Register an Application in Microsoft Entra ID

To register an application in Microsoft
Entra ID, follow the instructions in this link: https://learn.microsoft.com/en-us/mem/intune/developer/intune-graph-apis#register-apps-to-use-the-microsoft-graph-api

Make sure to select the following
permissions for Microsoft Graph API:

·      
Application permissions:
Sites.Selected

After registering the application, you will
need to note down the following information:

·      
Application (client) ID

·      
Directory (tenant) ID

·      
Client secret

You can find the application ID and the
directory ID in the Overview section of your application in Azure portal. To
generate a client secret, go to the Certificates and secrets section of your
application and click on New client secret.

Step 2: Get the SharePoint Site ID

To get the SharePoint site ID, you will
need to append _api/site/id to your SharePoint site
URL. For example, if your SharePoint site URL is
https://site.sharepoint.com/sites/GeneralComm, then you can get the site ID by
visiting https://site.sharepoint.com/sites/GeneralComm/_api/site/id. You will
see an XML response with a tag like this:

&lt;d:Id&gt;<GUID>&lt;/d:Id&gt;

Copy the value of the Id tag and save it
for later use.

Step 3: Grant Permissions to the SharePoint Site

To grant permissions to the SharePoint
site, you will need to run a PowerShell script that uses the Microsoft Graph
API to create a permission object for your application. The script will require
the following inputs:

·      
The SharePoint site ID that you
obtained in step 2.

·      
The application name that you
registered in step 1.

·      
The permission level that you
want to grant to the application. For example, write, read, or full control.

The script will also require you to connect
to Microsoft Graph and Azure AD using the Connect-MgGraph
and Connect-AzureAD cmdlets. You will need to provide
the application ID, the directory ID, and the client secret that you noted down
in step 1 as parameters for these cmdlets.

The script will then use the Invoke-MgGraphRequest cmdlet to send a POST request to the
Microsoft Graph API endpoint for creating permissions. The request will include
the site ID, the application ID, the application name, and the permission level
in the body. The script will also display the current and updated permissions
for the SharePoint site before and after the request.

You can copy and paste the following script
in a PowerShell editor and run it after replacing the values in the INPUTS
section with your own values.

 

 

# MS Graph PowerShell Modules Docs:
https://docs.microsoft.com/en-us/powershell/microsoftgraph/overview

# Installation (Run those commands – one
time setup)

#  
Set-ExecutionPolicyExecutionPolicy
RemoteSigned -Scope CurrentUser

#  
Install-Module Microsoft.Graph -Scope CurrentUser

#  
Import-Module Microsoft.Graph

 

# INPUTS

$siteId = "<Your GUID>" ###—> ENTER SHAREPOINT SITE ID HERE BY
ACCESSING HTTPS://SITE.sharepoint.com/sites/GeneralComm/_api/site/id

$appDisplayName = "Target App" ###—> ENTRA ID REGISTERED APPLICATION
NAME

$permission = "write"

 

# CONNECT

Connect-MgGraph -Scopes "Sites.Read.All","Sites.FullControl.All"

Connect-AzureAD

 

$sp = Get-AzureADServicePrincipal SearchString $appDisplayName 

$appId = $sp.AppId

 

$site = Get-MGSite SiteId $siteId

 

# TEST – Get Current Permissions

Write-Host "Before the update" ForegroundColor Green

$permissions = Get-MgSitePermission SiteId $siteId

$permissions | Select ExpandProperty GrantedToIdentities | Select ExpandProperty Application

 

# ADD – new Service Principal

$body = @{

  ‘roles’ = @(

      $permission

   );

  grantedToIdentities = @(

      @{

        ‘application’ = @{

          ‘id’ = $appId

          displayName = $appDisplayName

        }

      }

   );

}

 

$bodyJson = $body | ConvertTo-Json -Depth 10 -Compress

 

Invoke-MgGraphRequest `

    -Method POST `

    -Uri "v1.0/sites/$SiteId/permissions" `

    -Body $bodyJson

 

# TEST – Get Updated Permissions

Write-Host "After the update" ForegroundColor Green

$permissions = Get-MgSitePermission SiteId $siteId

$permissions | Select ExpandProperty GrantedToIdentities | Select ExpandProperty Application

 

Step 4: Upload a File to the SharePoint Site

To upload a file to the SharePoint site,
you will need to run another client-side PowerShell script that uses the
Microsoft Graph API to upload a file to a specific folder in the SharePoint
site. The script will require the following inputs:

·      
The SharePoint site ID that you
obtained in step 2.

·      
The folder path where you want
to upload the file. For example, /Files or /content.

·      
The local file path of the file
that you want to upload. For example, C:\ProgramData\Intune\Report.csv.

The script uses the Invoke-RestMethod cmdlet to send a PUT request to the Microsoft
Graph API endpoint for uploading files. The request will include the site ID,
the folder path, the file name, and the file content in the URL and the body.
The script will also check the response for the download URL of the uploaded
file and display a message if the upload is successful.

You can copy and paste the following script
in a PowerShell editor and run it after replacing the values in the INPUTS
section with your own values.

 

 

<#

This sample script is not supported under
any Microsoft standard support program or service.

The sample script is provided AS IS without
warranty of any kind.

Microsoft further disclaims all implied
warranties including, without limitation, any implied warranties of
merchantability or of fitness for a particular purpose.

The entire risk arising out of the use or
performance of the sample scripts and documentation remains with you.

In no event shall Microsoft, its authors,
or anyone else involved in the creation, production, or delivery of the
scripts be liable for any damages whatsoever (including, #without limitation,
damages for loss of business profits, business interruption, loss of business
information, or other pecuniary loss) arising out of the use of or inability
to use the sample scripts or documentation, even if Microsoft has been
advised of the possibility of such damages

#>

 

#Initialize Variables 1

$Machine = $env:COMPUTERNAME

$root = "C:\ProgramData\Intune"

$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"

$csvPath = "$($root)\$($Machine)_$timestamp.csv"

 

#Initialize Variables 2

#$global:authToken
= $null

$global:TenantID = ""  ## UPDATE TENANT ID

$global:ClientID = ""  ## UPDATE ENTRA ID APPLICATION ID

$global:ClientSecret = "" ## UPDATE CLIENT SECRET KEY

 

#Initialize Variables 3

$siteId = "<Your GUID>" # SPECIFY SHAREPOINT SITE ID

$folderPath = "/Files" #"/content"  # Path to the SharePoint folder
where you want to upload the file

$accessTokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"

$graphApiUrl = "https://graph.microsoft.com/v1.0/sites/$siteId/drive/items/root:$folderPath/"

 

# BEGIN

####################################################

# Function to retrieve auth token

Function Get-AuthToken {

       param(

             [Parameter(Mandatory=$true)]

             $TenantID,

             [Parameter(Mandatory=$true)]

             $ClientID,

             [Parameter(Mandatory=$true)]

             $ClientSecret

       )

       try{

             # Define parameters for Microsoft Graph
access token retrieval

             $resource = "https://graph.microsoft.com&quot;

             $authority = "https://login.microsoftonline.com/$TenantID"

             $tokenEndpointUri = "$authority/oauth2/token"

 

             # Get the access token using grant type client_credentials for Application Permissions

             $content = "grant_type=client_credentials&client_id=$ClientID&client_secret=$ClientSecret&resource=$resource"

             $response = Invoke-RestMethod -Uri $tokenEndpointUri -Body $content -Method Post UseBasicParsing

             #Write-Host "Got new Access
Token!" –ForegroundColor Green

        Write-Log -Message "Got new Access Token!" -severity 1 -component "UploadFile"

 

             # If the accesstoken
is valid then create the authentication header

             if($response.access_token){

             # Creating header for Authorization token

             $authHeader = @{

                    ‘Content-Type’=‘application/json

                    ‘Authorization’="Bearer " + $response.access_token

                    ExpiresOn=$response.expires_on

                    }

             return $authHeader

             }

             else{

                    Write-Error "Authorization Access Token is null,
check that the client_id and client_secret
is correct…"

                    break

             }

       }

       catch{

             #FatalWebError -Exception $_.Exception -Function "Get-AuthToken"

       }

}

####################################################

 

####################################################

# Function to calculate folder size

Function Get-FolderSize {

    param (

        [string]$folderPath

    )

 

    $folder = Get-Item $folderPath

 

    if ($folder -is [System.IO.DirectoryInfo]) {

        $size = 0

        Get-ChildItem $folder -Recurse | ForEach-Object {

            $size += $_.Length

        }

        return $size

    } else {

        return 0

    }

}

####################################################

 

####################################################

# LogWrite
function

Function Write-Log {

 

    PARAM(

         [String]$Message,

         [String]$Path = "$root\UploadFile.Log",

         [int]$severity,

         [string]$component

         )

        

         $TimeZoneBias = Get-CimInstance -Query "Select Bias from Win32_TimeZone"

         $Date = Get-Date -Format "HH:mm:ss.fff"

         $Date2 = Get-Date -Format "MM-dd-yyyy"

         $type =1

        

         "<![LOG[$Message]LOG]!><time=$([char]34)$date$($TimeZoneBias.bias)$([char]34) date=$([char]34)$date2$([char]34) component=$([char]34)$component$([char]34) context=$([char]34)$([char]34) type=$([char]34)$severity$([char]34) thread=$([char]34)$([char]34) file=$([char]34)$([char]34)>"| Out-File FilePath $Path -Append NoClobber -Encoding default

}

####################################################

# Create Root folder

if(!(Test-path $root)) { New-Item $root -ItemType Directory -Force | %{$_.Attributes = "hidden"} | out-null }

 

Write-Log -Message " " -severity 1 -component "UploadFile"

Write-Log -Message "Computer name: $($Machine)" -severity 1 -component "UploadFile"

Write-Log -Message "Root folder: $($root)" -severity 1 -component "UploadFile"

Write-Log -Message "Sharepoint
URL:
$($graphApiUrl)" -severity 1 -component "UploadFile"

 

# Retrieve Token

$global:authToken = Get-AuthToken TenantID $global:TenantID -ClientID $global:ClientID ClientSecret $global:ClientSecret

Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/v1.0/sites/$siteId" -Headers $global:authToken

 

# Get user profile folder

$userProfile = [System.IO.Path]::Combine($env:USERPROFILE, "Desktop")

 

# Get sizes of Desktop, Documents, and
Pictures folders

$desktopSize = $((Get-FolderSize "$env:USERPROFILE\Desktop") / 1MB)

$documentsSize = $((Get-FolderSize "$env:USERPROFILE\Documents") / 1MB)

$picturesSize = $((Get-FolderSize "$env:USERPROFILE\Pictures") / 1MB)

Write-Log -Message "Retrieved file sizes" -severity 1 -component "UploadFile"

 

# Hash table

$table = @()

$table += New-Object -TypeName PSCustomObject -Property @{

MachineName = $Machine

Desktop = "$([math]::Round($desktopSize,2)) MB"

Documents = "$([math]::Round($documentsSize,2)) MB"

Pictures = "$([math]::Round($picturesSize,2)) MB"

ExecutionTime = get-date -Format g

}

$table | select MachineName, Desktop, Documents, Pictures, ExecutionTime | export-csv -Path $csvPath NoTypeInformation

$localFilePath = (Get-ChildItem -path "C:\ProgramData\Intune" -Filter *.csv ErrorAction SilentlyContinue | Sort-Object -Descending | select -First 1).FullName

 

Write-Log -Message "Report exported" -severity 1 -component "UploadFile"

Write-Log -Message "Local file: $($localFilePath)" -severity 1 -component "UploadFile"

 

####################################################

# Function to retrieve auth token

Function Upload-File {

       param(

             [Parameter(Mandatory=$true)]

             $URL,

             [Parameter(Mandatory=$true)]

             $Token,

             [Parameter(Mandatory=$true)]

             $ContentType,

        [Parameter(Mandatory=$true)]

             $File

       )

       try

        {

                 $uploadUrl = $URL + (Split-Path $File -Leaf) + ":/content"

            $result = Invoke-RestMethod -Uri $uploadUrl -Method Put -Headers $Token InFile $File -ContentType $ContentType

            if($result.‘@microsoft.graph.downloadUrl)

                {

                    Write-Log -Message "File uploaded" -severity 1 -component "UploadFile"

                }

        }

       catch

        {

                 Write-Log -Message "Failed to upload file due to $($_.exception.message)" -severity 2 -component "UploadFile"

          
}

}

####################################################

 

Upload-File -URL $graphApiUrl -Token $global:authToken -File $localFilePath -ContentType "application/octet-stream"

 

 

 

The script above generates a log on the
client C:\ProgramData\Intune

 

 

 

A screenshot of a computer

Description automatically generated

 

 

Leave a comment

I’m Bindusar

Welcome to BINLABS, my cozy corner of the internet dedicated to IT admins and their daily encounter. Here, I invite you to join me for daily challenges with solution faced by admins using scripts. Let’s script together!

Let’s connect