As you probably already know, managing SharePoint Server can be a bit, well, cumbersome in on-premises environments. For that reason alone, many systems administrators go with SharePoint Online to simplify web content management.
Latest posts by Timothy Warner (see all)

You probably also understand that we use Windows PowerShell to automate our administrative work and reduce human errors. In this article, I’ll teach you how to manage your SharePoint Online farm programmatically from your administrative workstation by using only Windows PowerShell.

Windows PowerShell and SharePoint Online

Windows PowerShell and SharePoint Online

Setting up the environment

I trust that you already have a SharePoint Online subscription. Microsoft sells cloud-based SharePoint both as a standalone service and as a component in their Office 365 portfolio.

While we’re on the subject of trust and assumptions, you’ll need to be a global administrator of your SharePoint Online tenant (account) to perform PowerShell–based remote administration.

On your administrative workstation, go ahead and download/install the SharePoint Online Management Shell. Note that your system needs to be running at least Windows PowerShell 3.0; if it doesn’t, then make sure to nab Windows Management Framework 3.0 first.

Next, fire up an administrative PowerShell console session and look at the included cmdlets:

Get-Command -Module Microsoft.Online.SharePoint.PowerShell | Format-Wide -Column 2

Add-SPOUser                             Connect-SPOService
ConvertTo-SPOMigrationTargetedPackage   Disconnect-SPOService
Get-SPOAppErrors                        Get-SPOAppInfo
Get-SPODeletedSite                      Get-SPOExternalUser
Get-SPOMigrationJobProgress             Get-SPOMigrationJobStatus
Get-SPOSite                             Get-SPOSiteGroup
Get-SPOTenant                           Get-SPOTenantLogEntry
Get-SPOTenantLogLastAvailableTimeInUtc  Get-SPOTenantSyncClientRestriction
Get-SPOUser                             Get-SPOWebTemplate
New-SPOMigrationPackage                 New-SPOSite
New-SPOSiteGroup                        Remove-SPODeletedSite
Remove-SPOExternalUser                  Remove-SPOMigrationJob
Remove-SPOSite                          Remove-SPOSiteGroup
Remove-SPOTenantSyncClientRestriction   Remove-SPOUser
Repair-SPOSite                          Request-SPOPersonalSite
Request-SPOUpgradeEvaluationSite        Restore-SPODeletedSite
Set-SPOMigrationPackageAzureSource      Set-SPOSite
Set-SPOSiteGroup                        Set-SPOTenant
Set-SPOTenantSyncClientRestriction      Set-SPOUser
Submit-SPOMigrationJob                  Test-SPOSite

Okay. So we see that (a) the SharePoint Online module name is honkin’ long, and (b) all the SharePoint Online cmdlets start with the SPO noun prefix. The next thing you’ll notice is that there are far fewer cmdlets for SharePoint Online than for SharePoint on premises. Finally, you’ll see that the SharePoint Online cmdlets are good for site collection management and user/group administration, but they provide us with no visibility at the site/subsite/list/library level. That’s a major disadvantage, in my humble opinion.

Anyway, before we do any remote administration of our SharePoint Online site(s), we need to connect and authenticate to our tenant administration site. We use, appropriately enough, Connect-SPOService:

Connect-SPOService -Url -Credential

You’ll be asked to provide your password in a pop-up text box. Please note that you’ll get an error if you try to connect to one of your SharePoint Online sites. Instead, you need the tenant administration site. This URL normally takes the following form:

Interacting with your sites

You know how PowerShell works, right? We use Get- cmdlets to retrieve information about objects. In this case, we’ll start by enumerating all site collections within my SharePoint Online tenant with Get-SPOSite:

Get-SPOSite | Select-Object -Property Url
Get-SPOSite has a -filter parameter that we can use to isolate a particular site collection more quickly:
Get-SPOSite -Filter { Url -like '*search*' }
Url                                         Owner Storage Quota
---                                         ----- -------------                1000

Again, you’re correct in noticing that the SharePoint Online module has no built-in provision for inspecting sites, subsites, or lists and libraries. We’ll need to wait on Microsoft for an updated module. Alternatively, you can develop your own custom code to take advantage of the SharePoint client-side object model (CSOM) or its REST interface.

Because I know I have the most content in my top-level site collection, let’s put the object into a variable and see what properties are available:

$site = Get-SPOSite –Identity
$site | Get-Member –MemberType Property | Select-Object –Property Name | Format-Wide –Column 2
AllowSelfServiceUpgrade                 CompatibilityLevel
DenyAddAndCustomizePages                DisableSharingForNonOwnersStatus
LastContentModifiedDate                 LocaleId
LockIssue                               LockState
Owner                                   PWAEnabled
ResourceQuota                           ResourceQuotaWarningLevel
ResourceUsageAverage                    ResourceUsageCurrent
SandboxedCodeActivationCapability       SharingCapability
Status                                  StorageQuota
StorageQuotaWarningLevel                StorageUsageCurrent
Template                                Title
Url                                     WebsCount

We can now use “dot notation” to retrieve property values. Admittedly, there isn’t a whole lot to look at as of this writing in Summer 2015. As an example, let’s verify the site collection’s status:


Well, that was exciting (not!). I wonder what this site collection’s storage quota is?


The 1000 signifies 1000 megabytes, by the way. Perhaps that’s a bit too big—remember that, in the cloud, we pay based on resource utilization. Let’s use Set-SPOSite to reduce the storage quota to 800 MB and generate a warning when we’ve consumed 700 MB:

Set-SPOSite –Identity $site –StorageQuota 800 –StorageQuotaWarningLevel 700 -NoWait

While we’re at it, we can use Test-SPOSite to run site collection health checks on our site collections, and Repair-SPOSite to fix any errors. My site collection is fine, as you can see below:

Test-SPOSite -Identity -Verbose | Select-Object -Property PassedCount, FailedWarningCount, FailedErrorCount
PassedCount FailedWarningCount FailedErrorCount
----------- ------------------ ----------------
           7                  0                0

Creating and removing a new site collection

We’ll finish this tutorial with (somewhat of) a flourish by creating a new site collection programmatically. Here are the properties that we want our new site collection to have:

  • Template: wiki
  • URL: /sites/wiki
  • Storage Quota: 500
  • Time Zone: Central

We use Get-SPOWebTemplate to fetch the site collection template IDs:

Get-SPOWebTemplate | Select-Object -Property Name, Title
Name                     Title
----                     -----
STS#0                    Team Site
BLOG#0                   Blog
BDR#0                    Document Center
DEV#0                    Developer Site
OFFILE#1                 Records Center
EHS#1                    Team Site - SharePoint Online configuration
BICenterSite#0           Business Intelligence Center
SRCHCEN#0                Enterprise Search Center
ENTERWIKI#0              Enterprise Wiki
PROJECTSITE#0            Project Site
PRODUCTCATALOG#0         Product Catalog
COMMUNITY#0              Community Site
COMMUNITYPORTAL#0        Community Portal
SRCHCENTERLITE#0         Basic Search Center
visprus#0                Visio Process Repository

Believe it or not, specifying the time zone is required. According to this blog, my time zone (Central) is option value 11. Let’s code:

New-SPOSite -Url -Title "Test Wiki" -Owner "" -Template "ENTERWIKI#0" -TimeZoneId 11 -StorageQuota 500

The previous command throws an error if you specify http instead of https. Here’s an image of my SharePoint Online web portal, featuring our newly minted site collection:

We created the new wiki site collection

We created the new wiki site collection programmatically with PowerShell.

When you delete a site collection with Remove-SPOSite, the object actually goes to the Recycle Bin first:

Remove-SPOSite –Identity ''

To remove the object permanently, use Remove-SPODeletedSite:

Remove-SPODeletedSite –Identity '' -Confirm:$false

Be careful of adding the -Confirm:$false flag, especially for destructive actions such as nuking a SharePoint Online site collection.

Remember how we used Connect-SPOService to open the channel between our local computer and our SharePoint Online account? Microsoft gives us Disconnect-SPOService to cleanly close the connection and, more importantly, remove your stored account credentials.

In an interactive PowerShell session, simply closing the window implicitly removes all data from your runspace. However, you might consider adding Disconnect-SPOService to your PowerShell scripts to ensure that your stored credentials can’t be hijacked by malicious code elsewhere.

Closing thoughts

In my opinion, the SharePoint Online PowerShell cmdlets are feature-poor and woefully lacking in documentation. For instance, when you try to get help for the New-SPOSite cmdlet:

Get-Help –Name New-SPOSite –ShowWindow

You see a whole lot of nothing, as demonstrated in the following screenshot:

The SharePoint Online cmdlets have

The SharePoint Online cmdlets have almost non-existent documentation.

The disparity between SharePoint on premises and SharePoint Online PowerShell support is astounding. After all, SharePoint Server 2013 includes more than 600 native cmdlets!

In my view, the SharePoint Online cmdlets are best used as a way to enforce site collection governance. For example, you can script out how you want your SharePoint Online site collections defined.

Although I didn’t have time to go into it here, the SharePoint Online module does give you quite a bit of control over user and group accounts as well. Thanks for reading, and more Power to the Shell!


Leave a reply

Please enclose code in pre tags

Your email address will not be published.


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account