Home

SharePoint Online: PowerShell script to check and disable the IRM option into the SPLists

Highlighted
Fabrice Romelard
MVP

SharePoint Online: PowerShell script to check and disable the IRM option into the SPLists

In Office 365, the IRM solution has many impacts on the licensing model.

 

In some cases, you can have to implement the IRM option for only a couple of site collections, with a limited number of persons.

The issue is from license point of view, because the IRM activation is at the global level, but when it's done, any TeamSite Content Manager can enable the option into his list. But when it's done, the users who will access that SPList will have to be licensed with E3.

 

So to limit that license gap impact, you can use the following script preparing a CSV file like:

 

 

SiteCollectionURL;
https://mytenant.sharepoint.com/sites/mysitecollwithIRMaccepted;

 

 

The PowerShell will connect your tenant to get the Sites to check via the commands (getting the SPO TeamSites and SPO GroupSites):

 

 

$sitesInfo1 = Get-SPOSite -Template "STS#0" -IncludePersonalSite:$false  -Limit ALL | Sort-Object -Property url | Select *
$sitesInfo2 = Get-SPOSite -Template "GROUP#0" -IncludePersonalSite:$false  -Limit ALL | Sort-Object -Property url | Select *

$sitesInfo = $sitesInfo2 + $sitesInfo1  | Sort url 

Into that list, the script will look into all SPList placed into all subsites and check if the IRM is enable or not:

  • If no: it will be skipped with a line into the log
  • If yes: it will be disable into the concerned list and a line will be added into the log

At the end of that script the log will be zipped and sent via Email to the defined address. The disabled lists are placed into the body of that email too.

 

The full script is below:

 

[string]$GLOBAL:Logtofile = ""
[string]$GLOBAL:LogtoEmail = ""

[string]$username = "Adminaccount@tenant.onmicrosoft.com"
[string]$PwdTXTPath = "C:\SECUREDPWD\ExportedPWD-$($username).txt"

[string]$CSVExclusionFilePath = "C:\IRMCHECK\SiteCollectionsWithAuthorizedIRM.csv"

[string]$EmailAddressFrom = "supportteam@Yourdomain.com"
[string]$EmailAddressToSend = "supportteam@Yourdomain.com"
[string]$EmailSubject = "SHAREPOINT ONLINE IRM CHECK - "+ $(Get-Date).ToString("yyyy-MM-dd-hh:mm")
[string]$EmailSMTPServer = "smtp.Yourdomain.net"
[string]$EmailSMTPPort = "25"
$EmailencodingMail = [System.Text.Encoding]::UTF8

[string]$AllSiteWithListenableIRMLog = "AllSiteWithListenableIRM.log"
[string]$FolderDestinationLogFile = "D:\IRMCHECK\LOGS\"
[string]$DestinationLogFilePath = ""
[string]$ZippedLogFilePath = ""
[string]$MyRootFolderListURL = ""
$OFS = "`r`n"

[System.Diagnostics.Stopwatch] $sw; 
$sw = New-Object System.Diagnostics.StopWatch 
$sw.Start() 

function Load-DLLandAssemblies
{
	[string]$defaultDLLPath = ""
	# Load assemblies to PowerShell session 
	$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
	[System.Reflection.Assembly]::LoadFile($defaultDLLPath)

	$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
	[System.Reflection.Assembly]::LoadFile($defaultDLLPath)

	$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll"
	[System.Reflection.Assembly]::LoadFile($defaultDLLPath)
}

function Get-SPOWebs(){
param(
   $Url = $(throw "Please provide a Site Collection Url"),
   $Credential = $(throw "Please provide a Credentials")
)

  $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)  
  $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credential.UserName,$Credential.Password) 
  $context.RequestTimeout = 1000000 # milliseconds
  $web = $context.Web
  $context.Load($web)
  $context.Load($web.Webs)
  $context.ExecuteQuery()
  foreach($web in $web.Webs)
  {
       Get-SPOWebs -Url $web.Url -Credential $Credential 
       $web
  }
}

function Check-All-SPOWebLists(){
param(
   $Url = $(throw "Please provide a Site Collection Url"),
   $Credential = $(throw "Please provide a Credentials")
)
	$GLOBAL:Logtofile += " ------------------------------------------------------------------------------------ " + $OFS
	$GLOBAL:Logtofile += " Checks into the Subsite: "+ $Url + $OFS
	
	$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
	$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credential.UserName,$Credential.Password)
	$context.RequestTimeout = 1000000 # milliseconds
	$web = $context.Web
	$Mylists = $web.Lists;
	$Context.Load($Mylists)
	$Context.ExecuteQuery();
	Write-host "     -------------------- CHECK IN LISTS -------------------- "
	foreach($myList in $MyLists)
	{
		Write-host "           ==== List Name:", $mylist.Title  -ForegroundColor Magenta
		if($mylist.IrmEnabled)
		{
			Write-host "                IRM Status (IrmEnabled):", $mylist.IrmEnabled -ForegroundColor Red
			Write-host "                >>> NEED TO CONTROL OR DISABLE THE SETTING" -ForegroundColor Red
			
			# GET the Owner if possible ??
			
			#Force the IRM Disable at the list level
			$mylist.IrmEnabled = $false
			$mylist.Update()
			$Context.ExecuteQuery()
                 
			#Logging the change
			$GLOBAL:Logtofile += " IRM ACTIVE from the list: "+ $mylist.Title +" - in SPWeb: "+ $Url + $OFS
			$GLOBAL:LogtoEmail += " IRM ACTIVE from the list: "+ $mylist.Title +" - in SPWeb: "+ $Url + $OFS
		}
		else
		{
			Write-host "                IRM Status (IrmEnabled):", $mylist.IrmEnabled -ForegroundColor Green
			$GLOBAL:Logtofile += "   IRM Not active from the list: "+ $mylist.Title +" - in SPWeb: "+ $Url + $OFS
		}
	}
	$GLOBAL:Logtofile += " ------------------------------------------------------------------------------------ " + $OFS

}

cls
Write-Host " ---------------------------------------------- "
Load-DLLandAssemblies
Write-Host " ---------------------------------------------- "

$secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath)
$adminCreds = New-Object System.Management.Automation.PSCredential $username, $secureStringPwd

Connect-SPOService -Url https://tenant-admin.sharepoint.com -credential $adminCreds -ErrorAction SilentlyContinue -ErrorVariable Err

Write-host " -------------------------------------------------------------------------------------------- " -ForegroundColor green
$SiteToExcludeList = Import-Csv -encoding UTF8 $CSVExclusionFilePath -delimiter ";"
#$SiteToExcludeList | Format-Table
Write-host "   >>> CSV File content loaded:", $CSVExclusionFilePath, "- Total Lines:", $SiteToExcludeList.count -ForegroundColor Yellow
Write-host " -------------------------------------------------------------------------------------------- " -ForegroundColor green

$TempPathFilename = $(Get-Date).ToString("yyyyMMdd-hhmmss-fff")+"_"+ $AllSiteWithListenableIRMLog
$DestinationLogFilePath = Join-Path -Path $FolderDestinationLogFile -ChildPath $TempPathFilename
if (Test-Path $DestinationLogFilePath)
{
    Remove-Item $DestinationLogFilePath -Force
}

#Retrieve all site collection infos (GroupSite and Classic TeamSite)
$sitesInfo1 = Get-SPOSite -Template "STS#0" -IncludePersonalSite:$false  -Limit ALL | Sort-Object -Property url | Select *
$sitesInfo2 = Get-SPOSite -Template "GROUP#0" -IncludePersonalSite:$false  -Limit ALL | Sort-Object -Property url | Select *

$sitesInfo = $sitesInfo2 + $sitesInfo1  | Sort url 
#$sitesInfo = $sitesInfo1  | Sort url | Select-Object -First 2 #TO CHECK ONLY THE FIRST 2 CLASSIC TEAMSITE COLLECTION

Write-Host "--------------------------------------------------------------------------------------------"
Write-Host " =>>>>>>>  Site collections number to check:", $sitesInfo.count -ForegroundColor Magenta
Write-Host "--------------------------------------------------------------------------------------------"

foreach($SiteToExclude in $SiteToExcludeList)
{
	$sitesInfo = $sitesInfo | where {$_.url -ne $SiteToExclude.SiteCollectionURL} #remove all the excluded items from the site list
}

Write-Host "--------------------------------------------------------------------------------------------"
Write-Host " =>>>>>>>  Site collections number to check:", $sitesInfo.count -ForegroundColor Magenta
Write-Host "--------------------------------------------------------------------------------------------"

$GLOBAL:Logtofile += "--------------------------------------------------------------------------------------------" + $OFS
$GLOBAL:Logtofile +=  " =>>>>>>>  Site collections number to check: "+ $($sitesInfo.count) + $OFS
$GLOBAL:Logtofile +=  "--------------------------------------------------------------------------------------------" + $OFS

#Retrieve and print all sites
foreach ($site in $sitesInfo)
{
	#$SiteToExcludeList |Where-Object {$_.SiteCollectionURL -match $site.Url}

	Write-Host "==================================================================================================="
	Write-Host " => SPO Site collection:", $site.Url, "- Title:", $site.Title -ForegroundColor green
	Write-Host "   => External Sharing:", $site.SharingCapability, "- Site Template Used:", $site.Template
	Write-Host "--------------------------------------------------------------------------------------------"

	$GLOBAL:Logtofile += "===================================================================================================" + $OFS
	$GLOBAL:Logtofile += " => SPO Site collection: "+ $($site.Url) +" - Title: "+ $($site.Title) + $OFS
	$GLOBAL:Logtofile += "   => External Sharing: "+ $($site.SharingCapability) +" - Site Template Used: "+ $($site.Template) + $OFS
	$GLOBAL:Logtofile += "--------------------------------------------------------------------------------------------" + $OFS

	# ===> TO DO AND GET THE OFFICIAL SITE OWNER
	#Write-Host "   => Owner:", $site.Owner

	Check-All-SPOWebLists  -Url $site.Url -Credential $adminCreds -MyLogToFill 

    $AllWebs = Get-SPOWebs -Url $site.Url -Credential $adminCreds
    
	foreach($MySPWeb in $AllWebs)
	{
		$GLOBAL:Logtofile += " ------------------------------------------------------------------------  " + $OFS
		$GLOBAL:Logtofile += "    => Subsite: "+ $($MySPWeb.Url) +" - Title: "+ $($MySPWeb.Title) + $OFS
		Write-Host "--------------------------------------------------------------------------------------------" -ForegroundColor yellow
		Write-Host "        ==>>", $MySPWeb.Title, "-", $MySPWeb.Url -ForegroundColor yellow
		Check-All-SPOWebLists  -Url $MySPWeb.Url -Credential $adminCreds -MyLogToFill 
	}
    Write-Host "--------------------------------------------------------------------------------------------"
	$GLOBAL:Logtofile += " ------------------------------------------------------------------------  " + $OFS
} 

$sw.Stop()

Write-host " ===================================================================================================" -ForegroundColor Green
write-host "     ===>>>>IRM Check and fix: ", $sw.Elapsed.ToString() -foreground Yellow
Write-host " ===================================================================================================" -ForegroundColor Green

$GLOBAL:Logtofile += " ===================================================================================================" + $OFS
$GLOBAL:Logtofile += "     ===>>>>IRM Check and fix: "+ $($sw.Elapsed.ToString()) + $OFS
$GLOBAL:Logtofile += " ===================================================================================================" + $OFS

if($GLOBAL:LogtoEmail -eq "")
{
	$GLOBAL:LogtoEmail += " There is no place where IRM is enable" + $OFS + $OFS
}

$GLOBAL:LogtoEmail += " ===================================================================================================" + $OFS
$GLOBAL:LogtoEmail += "  FIND THE DETAILS INTO THE LOG FILE AVAILABLE INTO THE SERVER FOLDER: "+ $DestinationLogFilePath + $OFS
$GLOBAL:LogtoEmail += " ===================================================================================================" + $OFS

add-content -Encoding UTF8 -Path $DestinationLogFilePath -Value $GLOBAL:Logtofile -Force

#Add the ZIP Action for the generated log file
$ZippedLogFilePath = $DestinationLogFilePath +".zip"
Compress-Archive -LiteralPath $DestinationLogFilePath -CompressionLevel Optimal -Update -Force -DestinationPath $ZippedLogFilePath

Send-MailMessage -From $EmailAddressFrom -to $EmailAddressToSend -Subject $EmailSubject -Body $GLOBAL:LogtoEmail -SmtpServer $EmailSMTPServer -port $EmailSMTPPort -Attachments $ZippedLogFilePath -Encoding $EmailencodingMail

You can use and adapt that script as you want to.

 

Fabrice Romelard

 

Sources used:

 

 

French version:

Related Conversations
Embedding on SharePoint
Audrie Gordon in Microsoft Stream Forum on
46 Replies
External Sharing with Stream or Video
Jennifer Seitsinger in Microsoft Stream Forum on
50 Replies
Excel Share document look and feel
Jerry Gonzalez in Excel on
8 Replies
Adding a user or sending download link
Scott Mackay in Office 365 on
8 Replies