PackageManagement\Install-Package : No match was found…

As ever, creating this note as a reminder and to save me trawling Google the next time the problem occurs.

When attempting to install a PowerShell module and the following error happens…

PackageManagement\Install-Package : No match was found for the specified search criteria and module name 'AzureAD'. Try Get-PSRepository to see all available registered module repositories.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\\PSModule.psm1:1809 char:21

… it can be resolved by running this command.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


Looping through SPList items

Now this is something I’m guilty of time and time again. Within my PowerShell scripts I quite often query SharePoint lists and loop through them in the following way…

$site = New-Object Microsoft.SharePoint.SPSite( $url )
$web = $site.OpenWeb()
$list = $web.List

for ( $i = 0; $i < $list.Items.Count; $i++) {
   SPListItem listItem = activeList.Items[i];

What I should be doing is this…

SPListItemCollection items = SPContext.Current.List.Items;

for(int i=0;i<100 && i<items.Count;i++) {
  SPListItem listItem = items[i];


For whatever reason, sometimes you just can’t upgrade the installed version of PowerShell on a server. In this case, I wanted to make use of the Invoke-SqlCommand command.

The most simple way around this limitation is to add a module to the server that includes a command that performs the same function.

Jourdan Templeto’s Simple SQL in PowerShell post has a cmdlet that can be cut and pasted into a new PowerShell module file and then easily accessed from your own scripts. Simple.


Adding users to a Yammer group

I’m making a note of this blog post as I can foresee a future need to be able to subscribe specific subsets of users to Yammer groups.

How To Add A User To Yammer Group Using PowerShell

Also see the official documentation for /group_memberships.json


Task Scheduler & PowerShell

To manage repeating tasks, its common for us (the team I work with 9-5) to automate things with a PowerShell script and then schedule it to repeat at specific times using a scheduled task.

When I create the task I use a specific set of parameters , which I always forget – so I’m noting them here for future reference.

PowerShell.exe -NoProfile -ExecutionPolicy ByPass -File C:\PowerShell\Get-SomethingNice.ps1


Creating SharePoint alerts via CSOM

I’m posting this as a useful reminder. It outlines how alerts can now be created via CSOM.

New SharePoint CSOM version released for SharePoint Online – February 2017

The included code sample is in C#, but I’ve translated it to PowerShell – which suits my administrative needs better.

[System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.SharePoint.Client" ) | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.SharePoint.Client.Runtime" ) | Out-Null

# Set variables
$path = "C:\Temp\Usernames.txt"

$url = ""

$list = "My List"

$title = "$list (Auto-subscribed)"

# Prompt the administrator to log in
$credential = Get-Credential -Credential $null

# Create a connection to SharePoint Online
$context = New-Object Microsoft.SharePoint.Client.ClientContext( $url )
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials( $credential.UserName, $credential.Password )

# Retrieve the targeted web
$web = $context.Web

$context.Load( $web )

# Loop through the provided usernames and create a new alert for each one
$usernames = Get-Content -Path $path

foreach ( $username in $usernames )
    $user = $context.Web.EnsureUser( $username )

    $alert = New-Object Microsoft.SharePoint.Client.AlertCreationInformation
    $alert.List = $context.Web.Lists.GetByTitle( $list )
    $alert.AlertFrequency = [Microsoft.SharePoint.Client.AlertFrequency]::Daily
    $alert.AlertTime = ( Get-Date ).AddDays( 1 )
    $alert.AlertType = [Microsoft.SharePoint.Client.AlertType]::List
    $alert.AlwaysNotify = $false
    $alert.DeliveryChannels = [Microsoft.SharePoint.Client.AlertDeliveryChannel]::Email
    $alert.Status = [Microsoft.SharePoint.Client.AlertStatus]::On
    $alert.Title = $title
    $alert.User = $user
    $alert.EventType = [Microsoft.SharePoint.Client.AlertEventType]::All
    $alert.Filter = "1"

    $guid = $user.Alerts.Add( $alert )



Secure credentials within PowerShell

For PowerShell scripts that need to access resources (e.g. a site within SharePoint) and be run as scheduled tasks, I will normally use an encrypted password…

Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString | Out-File "$PSScriptRoot\Password.txt"

… and then refer to it within my script.

$username = ""
$password = Get-Content "$PSScriptRoot\Password.txt"

$securePassword = $password | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PSCredential( $username, $securePassword )

This <a href="">blog post by Kloud</a> covers some this technique in greater detail.

SharePoint Content Type IDs

This is a handy PowerShell snippet for returning a list of all Content Types and their IDs within a SharePoint site.

$site = Get-SPSite
$web = $site.RootWeb
ForEach( $contentType in $web.ContentTypes ) { Write-Host $contentType.Name": "$contentType.ID }

Using PowerShell To Analyse The Contents Of A Folder

# The path to interrogate
 $targetPath = "X:\Shared\FolderToBeInterrogated"
# The path to save the exported report
 $exportPath = "C:\Reports"
# Recursively get all files
 Get-ChildItem -Path $targetPath -Recurse -Force | Select Name, Extension, Length, CreationTime, LastWriteTime, LastAccessTime, FullName | Export-Csv -NoTypeInformation -Force "$exportPath\Report $( Get-Date -f yyyy-MM-dd ).csv"

Trouble Shooting SharePoint Errors

For viewing in command prompt:

Get-SPLogEvent | ?{$_.Correlation -eq "<GUID>"} | SELECT Area, Category, Level, EventID, Message | Format-List

Export the results as text file:

Get-SPLogEvent | ?{$_.Correlation -eq "<GUID>"} | SELECT Area, Category, Level, EventID, Message | Format-List > C:\Error.log

Results can be retrieved faster if the time span is limited:

Get-SPLogEvent -StartTime YYYY-MM-DDTHH:mm:ss | ?{$_.Correlation -eq "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"} | SELECT Area, Category, Level, EventID, Message | Format-List