使用 Windows PowerShell 管理 SharePoint Online

 

上一次修改主题: 2015-03-09

**摘要:**使用 Windows PowerShell 来管理使用 Windows PowerShell cmdlet、脚本和批处理过程的 Office 365。

可以使用 SharePoint Online cmdlet 管理 SharePoint Online。(是否会看到并非所有软件名称都是晦涩难懂的?)在当前 Incarnation 中,Windows PowerShell 的 SharePoint Online 实现方式在某种程度上受到限制:Office 365 管理员只能使用 30 个 cmdlet,且目前您无法使用 Windows PowerShell 管理 OneDrive Pro、SharePoint Online 搜索、SharePoint Online 术语库、用户配置文件等。这是否说明没有理由使用 Windows PowerShell 管理 SharePoint Online?我们先不要草率地下此定论。实际上 SharePoint Online 的许多关键部分不仅可以使用 Windows PowerShell 进行管理,而且还能使用 Windows PowerShell 管理得极为出色。

使用 Windows PowerShell 管理 SharePoint Online

本主题涵盖下列内容:

  • 使用 SharePoint Online 站点

  • 处理 SharePoint Online 用户

  • 处理 SharePoint Online 网站用户组

  • 关于 ForEach-Object Cmdlet 的提示

有关使用 Windows PowerShell 管理 SharePoint Online 的详细信息,您可能希望查看 SharePoint Online cmdlet 参考,此处提供了一组帮助主题。

另外,请不要忘记以下两篇文章,其中包含了 SharePoint Online 的很多有用的 Windows PowerShell 命令:

使用 SharePoint Online 站点

我们能否列举出可通过 Windows PowerShell 管理的 SharePoint Online 相关示例区域?我们当然可以。Windows PowerShell 真正实用的地方在于可帮助您识别 SharePoint Online 站点的子集。在大型组织中,拥有许多站点很正常,甚至可能拥有成百上千个站点。这有什么不妥之处吗?当然没有。不过,假设您拥有数百个站点,并想知道有多少个站点属于 wiki;也就是说,您想知道有多少个站点是使用企业 Wiki 模板(官方名称为 ENTERWIKI#0)构建的。能否通过 SharePoint Online 管理中心找到此类信息?我们不会说您无法通过这种方法找到此类信息,但操作起来并不是一件容易的事。肯定不如运行一个 Windows PowerShell 命令简单,如下所示:

Get-SPOSite | Where-Object {$_.Template -eq "ENTERWIKI#0"}

也就是说,我们使用 Get-SPOSite cmdlet 返回与我们的所有站点相关的信息,然后使用 Where-Object cmdlet 仅选出 Template 属性等于 ENTERWIKI#0 的站点。

备注

我们如何知道企业 Wiki 模板的官方名称为 ENTERWIKI#0?这个问题很简单:我们只需运行以下命令即可:
Get-SPOWebTemplate

或者,您可能想获取存储配额大于 1000 兆字节或小于 250 兆字节的所有站点的列表。能否通过 Windows PowerShell 快速轻松地做到这一点?当然可以:

Get-SPOSite | Where-Object {$_.StorageQuota -gt 1000 -or $_.StorageQuota -lt 250}

这可能比我们到目前为止看到的一些查询更为复杂一些,但是在您了解行业术语后,您应该能够理解具体的工作原理。在此示例中,我们要查找符合以下两个条件之一的站点。无论哪个站点:1) StorageQuota 大于 (-gt) 1000 兆字节;或者 (-or) 2) StorageQuota 小于 (-lt) 250 兆字节。假设我们有 4 个站点:

站点 StorageQuota

站点 A

180

站点 B

700

站点 C

300

站点 D

1500

在此示例日期,站点 A 会返回,因为它的 StorageQuota 小于 250。站点 D 也会返回,因为它的 StorageQuota 大于 1000。站点 B 和站点 C 由于不符合任何条件而不会返回。

我们介绍下面的另外一示例只是因为比较有趣。假设您想获取管理员未拥有的所有站点的列表;也就是说,Owner 不等于 admin@litwareinc.onmicrosoft.com 的所有站点。该命令很容易编写,不会编写就实在太尴尬了:

Get-SPOSite | Where-Object {$_.Owner -ne "admin@litwareinc.onmicrosoft.com"}

不过,不能因为容易编写就忽略它的实用性,对吗?

处理 SharePoint Online 用户

Windows PowerShell 是一个非常有用的工具,可用于处理 SharePoint Online 网站用户。首先,您可以使用 Windows PowerShell 和 Get-SPOUser cmdlet 返回所有已被授予网站访问权限的用户列表。这个问题很简单:

Get-SPOUser -Site "https://litwareinc.sharepoint.com/sites/finance"

您只需调用 Get-SPOUser,后接您感兴趣的网站的 URL。

或者,如果您只想返回具有网站访问权限的用户(而不是组),您可以使用此命令:

Get-SPOUser -Site "https://litwareinc.sharepoint.com/sites/finance" | Where-Object {$_.IsGroup -eq $False}

这也很容易:我们只需请求 IsGroup 属性设置为 False 的网站用户。(在 Windows PowerShell 中编写命令时,需使用 $True 和 $False,而不是普通的旧 True 和 False。)

只返回作为网站管理员的用户同样很简单,也就是返回 IsSiteAdmin 属性为 True 的用户:

Get-SPOUser -Site "https://litwareinc.sharepoint.com/sites/finance" | Where-Object {$_.IsSiteAdmin -eq $True}

但这只限于单个网站。当您需要处理多个对象(比如多个网站)时,Windows PowerShell 的强大之处往往会彰显无遗。例如,返回有权访问给定网站的所有用户列表是轻而易举的。但是,如果反过来会怎样:如果要返回单个用户有权访问的所有网站列表,该怎么办呢?您可以使用 Windows PowerShell 做到这一点吗?您当然可以。下面是一个简单的小脚本(不可否认,这对于那些​​拥有一些 Windows PowerShell 经验的用户而言非常简单),可返回特定用户(在本例中是 Ken Myer)有权访问的所有网站的名称:

$x = (Get-SPOSite).Url

foreach ($y in $x)
    {
        $z = $Null
        $z = Get-SpoUser -Site $y | Where-Object {$_.DisplayName -eq "Ken Myer"}
        if ($z -ne $Null) {$y}
    }

备注

如何在 Windows PowerShell 中使用脚本?如下:复制上面的代码,将其粘贴到记事本(或其他文本编辑器)中,然后使用 .ps1 文件扩展名(例如,C:\Scripts\SitesAUserCanAccess.ps1)保存该文件。若要运行该脚本,请使用 Windows PowerShell 连接到 SharePoint Online,然后在 Windows PowerShell 命令提示符下,只需键入 .ps1 文件的路径,然后按 ENTER 键即可:
C:\Scripts\SitesAUserCanAccess.ps1

或者,如果要返回所有网站的列表,以及这些网站的管理员,该怎么办呢?可以使用单个命令返回这些信息:

Get-SPOSite | ForEach-Object {Write-Host $_.Url; Get-SPOUser -Site $_.Url | Where-Object {$_.IsSiteAdmin -eq $True}}

您应该会收到类似于以下的内容:

https://litwareinc.sharepoint.com/sites/communities
MOD Administrator  admin@litwareinc.com {Communities Members, Comm...}
Sara Davis  sarad@litwareinc.com {Communities Members, Communities...}

https://litwareinc.sharepoint.com/sites/finance
MOD Administrator admin@litwareinc.com {Excel Services Viewers, Hi...}

https://litwareinc.sharepoint.com/sites/hr
MOD Administrator  admin@litwareinc.com   {Contoso Beta Members, C...}

诚然,这并非史上最漂亮的输出,但是毋庸赘言,外表并非一切。等到您获取更多经验并能更加熟练地使用 Windows PowerShell 以后,您将学习如何以各种很酷的方式对这些输出进行自定义。

最重要的是,Windows PowerShell 不只是一种用于检索信息的途径:它还可用于配置内容。假设您有几百个网站,并且需要使 Ken Myer 成为每个网站的管理员,您只需询问:

Get-SPOSite | ForEach-Object {Set-SPOUser -Site $_.Url -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True}

很不错,是吧?

处理 SharePoint Online 网站用户组

别担心:我们没有忘记网站用户组。事实上,Windows PowerShell 是管理您的 SharePoint 网站用户组的一种好方法。SharePoint Online 管理中心具有一些易于使用的网站用户组管理方法,但实现这些方法可能有点麻烦。例如,假设您想要查看网站 https://litwareinc.com/sites/finance 的用户组和用户组成员。您需要执行以下操作:

  1. 在 SharePoint Online 管理中心的“网站集”选项卡上,单击网站的名称。

  2. 在“网站集属性”对话框中,单击链接打开 https://litwareinc.com/sites/finance。

  3. 在网站页面上,单击“设置”图标(位于页面的右上角),然后单击“网站设置”:

    SharePoint Online“网站设置”选项。

  4. 在“网站设置”页中,单击“网站和权限”。

然后对您要查看的下一个网站重复此过程。

那么,有没有另一种方法,可以从给定的网站获取所有用户组及其用户的列表?嗯,至少还有另外一种方法:

$x = Get-SPOSiteGroup -Site "https://litwareinc.com/sites/finance"

foreach ($y in $x)
    {
        Write-Host $y.Title -ForegroundColor "Yellow"
        Get-SPOSiteGroup -Site "https://litwareinc.com/sites/finance" -Group $y.Title | Select-Object -ExpandProperty Users
        Write-Host
    }

不可否认,与我们到目前为止已经为您显示的大多数命令相比,上述脚本略显复杂。而且还有一点麻烦:毕竟,您需要复制代码,并将其粘贴到记事本(或其他文本编辑器)中,使用 .ps1 文件扩展名(例如,C:\Scripts\SiteGroupsAndUsers.ps1)来保存文件,然后从 Windows PowerShell 中运行该脚本。尽管如前文所述,它是有一点麻烦;毕竟,仅运行该脚本就需要键入 .ps1 文件的完整路径:

C:\Scripts\SiteGroupsAndUsers.ps1

因此,当中涉及的工作量要多一点。但是,看看我们能从这极小的工作量中获得怎样的回报吧:

网站用户组和网站用户组成员。

这些是为网站 https://litwareinc.com/sites/finance 创建的所有用户组,以及分配给这些用户组的所有用户。(而且,只是为了醒目,我们用黄色显示用户组名,以帮助您分辨用户组及其成员列表。

如果您认为这很了不起,请先别急,等等来看这个脚本:

$x = Get-SPOSite

foreach ($y in $x)
    {
        Write-Host $y.Url -ForegroundColor "Yellow"
        $z = Get-SPOSiteGroup -Site $y.Url
        foreach ($a in $z)
            {
                 $b = Get-SPOSiteGroup -Site $y.Url -Group $a.Title 
                 Write-Host $b.Title -ForegroundColor "Cyan"
                 $b | Select-Object -ExpandProperty Users
                 Write-Host
            }
    }

该脚本会针对您的所有 SharePoint Online 网站逐一列出所有用户组和所有用户组成员。试一试,亲身体会一下。

现在明白为什么您可能需要使用 Windows PowerShell 管理 SharePoint Online 的原因吧了?

关于 ForEach-Object Cmdlet 的简短说明

在处理 SharePoint Online 用户中,您可能已经注意到我们通过管道将站点信息传递到 ForEach-Object cmdlet:

Get-SPOSite | ForEach-Object {Set-SPOUser -Site $_.Url -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True}

这便引出一个颇为有趣的问题:我们为什么要这样做?毕竟,在使用 Azure Active Directory cmdlet 时,我们直接通过管道将信息从 Get-MsolUser cmdlet 传递到 Set-MsolUser cmdlet:

Get-MsolUser | Set-MsolUser -UsageLocation "FR"

那么,我们为什么不对 SharePoint Online 命令执行类似的操作:

Get-SPOSite | Set-SPOUser -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True

主要原因是这样做并不起作用。使用 Set-SPOUser cmdlet 时,您必须明确地添加 Site 参数(后跟站点名称)。例如:

Set-SPOUser -Site "https://litwareinc.sharepoint.com/sites/communities" -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True

也就是说,如果我们尝试通过管道将信息直接传递到 Set-SPOUser,则 cmdlet 不会提取全部的站点,也不会将 Ken Myer 设置为每个站点的管理员。相反,它会提示我们输入站点 URL:

Get-SPOSite | Set-SPOUser -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True
cmdlet Set-SPOUser at command pipeline position 2
Supply values for the following parameters:
Site: 

也就是说,我们需要通过管道将站点信息改为传递到 ForEach-Object cmdlet。ForEach-Object 可以提取传递给它的每个项目(每个站点),然后完全按照我们的指示对每个项目执行操作。在此示例中,我们指示它使用 Set-SPOUser cmdlet 将 Ken Myer 设置为相应站点的管理员:

Set-SPOUser -Site $_.Url -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True

语法 $_.Url 代表站点 URL。**$_.**表示我们使用的信息是由其他 cmdlet 通过管道传递到 ForEach-Object cmdlet。

感到很困惑?下面介绍了一个简单示例。假设我们有三个站点,URL 如下所示:

在我们通过管道将相应的信息传递到 ForEach-Object 后,该 cmdlet 会提取集合中的第一个项目(站点 1),并使用该站点 URL 运行 Set-SPOUser cmdlet。也就是说,它会运行以下命令:

Set-SPOUser -Site "https://litwareinc.sharepoint.com/sites/site1" -LoginName "kenmyer@litwareinc.com" -IsSiteCollectionAdmin $True

完成后,它会提取第二个站点(站点 2),并针对该站点运行 Set-SPOUser:

Set-SPOUser –Site "https://litwareinc.sharepoint.com/sites/site1" –LoginName "kenmyer@litwareinc.com" –IsSiteCollectionAdmin $True

正如您所看到的,它现在使用的是集合中的第二个站点的 URL。最终,ForEach-Object 会提取集合中的所有站点,并将 Ken Myer 设置为每个站点的管理员。

有关详细信息,请参阅本文。毋庸置疑,实际上 ForEach-Object 是我们了解的比较方便使用的 cmdlet。例如,有时当您尝试通过管道将信息从一个 cmdlet 传递到另一个 cmdlet 时,可能会看到以下错误消息:

The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

出现此错误消息是因为并非所有的 cmdlet 都接受管道输入。如何解决该问题?是的,原因是:使用 ForEach-Object。

另请参阅

使用 Windows PowerShell 管理 Office 365 的最佳方式