徵兆
安裝 Microsoft SharePoint Server 的下列 10 月安全性更新之後,可能會封鎖某些 Microsoft SharePoint 2010 工作流程案例。 此外,「6ksbk」事件標記會記錄在 SharePoint 統一記錄系統 (ULS) 記錄中。
原因
為了加強 SharePoint 工作流程的安全性,SharePoint 現在僅支援工作流程 .xoml 檔案的 UTF-8 字元編碼。
附註: 根據預設,SharePoint 工作流程工具 (例如 SharePoint 設計工具、Microsoft Visual Studio 和 Nintex) 會使用 UTF-8 字元編碼建立工作流程 .xoml 檔案。 除非客戶已手動編輯工作流程 .xoml 檔案,並將其轉換成不同的字元編碼,否則他們不會受到此安全性改善的影響。 此問題有記載於此知識庫文章中,說明客戶選擇這麼做的可能性微乎其微。
因應措施
如果您已手動編輯工作流程 .xoml 檔案,並將其轉換成 UTF-8 以外的字元編碼,則必須重新編輯檔案,才能將其轉換回 UTF-8。 請確認檔案的 XML 宣告將編碼定義為 UTF-8,使用文字編輯器以 UTF-8 字元編碼格式儲存檔案,然後將其重新部署。
可在 SharePoint 管理殼層中使用以下 PowerShell 指令碼掃描 SharePoint 網站集合中的工作流程 .xoml 檔案,以確定其是否受到此變更的影響。 對於不使用 UTF-8 字元編碼且與此變更相容的工作流程 .xoml 檔案,IsGoodWorkflow 輸出將為 True。 對於不使用 UTF-8 字元編碼且需要修改的工作流程 .xoml 檔案,IsGoodWorkflow 輸出將為 False。
<#
.SYNOPSIS
Script to check character encoding of workflow .xoml files found in a site collection.
.DESCRIPTION
This script checks the character encoding of workflow .xoml files found in a site collection based
on the security improvement documented here: https://support.microsoft.com/topic/sharepoint-2010-workflows-might-be-blocked-by-enhanced-security-policy-kb5020238-eb91e24d-eea4-4490-a281-86503adc8b27
This could be altered to take an SPWebApplication object, iterate through all SPSite objects in the Sites SPSiteCollection,
and then iterate through all SPWeb subsites in the AllWebs SPWebCollection.
.EXAMPLE
Get-WorkflowStatusForSite -SiteCollectionUrl https://sharepoint
.EXAMPLE
Get-WorkflowStatusForSite -SiteCollectionUrl https://sharepoint -IgnoreSubSites
.INPUTS
None
.OUTPUTS
PSCustomObject with Site, Web, WorkflowFileName and IsGoodWorkflow Result
Site Web WorkflowFileName IsGoodWorkflow
---- --- ---------------- --------------
SPSite Url=http://sharepoint http://sharepoint/WorkflowTest 2010 Log Workflow.xoml True
SPSite Url=http://sharepoint http://sharepoint/WorkflowTest Another Test Log.xoml True
.NOTES
Version .1
#>
param(
[Parameter(Position=2,HelpMessage="The site collection URL to validate.")]
[string]$SiteCollectionUrl,
[Parameter(Position=3,HelpMessage="Ignore subsites below the top-level site in the site collection.")]
[switch]$IgnoreSubSites
)
function IsGoodWorkflow
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[System.Xml.XmlReader]$xmlReader
)
try {
$xDoc = [System.Xml.Linq.XDocument]::Load($xmlReader)
if ($null -ne $xDoc -and $null -ne $xDoc.Declaration -and $null -ne $xDoc.Declaration.Encoding)
{
if ($xdoc.Declaration.Encoding.ToLower() -ne "utf-8")
{
return $false
}
}
}
catch
{
return $false
}
return $true
}
function CheckWorkflowFile
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[Microsoft.SharePoint.SPFile]$SPFile
)
$xmlReader = [System.Xml.XmlReader]::Create($SPFile.OpenBinaryStream())
if ($null -ne $xmlReader)
{
$isGood = $xmlReader | IsGoodWorkflow
$xmlReader.Close()
$xmlReader.Dispose()
return [PSCustomObject]@{
Site = $SPFile.Item.Web.Site
Web = $SPFile.Item.Web.Url
WorkflowFileName = $SPFile.Name
IsGoodWorkflow = $isGood
}
}
}
function CheckWorkflowsForWeb
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[Microsoft.SharePoint.SPWeb]$SPWeb
)
write-host "Checking $SPweb"
$WorkflowsList = $SPWeb.Lists["Workflows"]
$results = @()
if ($WorkflowsList)
{
Write-Host "Found: " $WorkflowsList.Title
foreach ($listItem in $WorkflowsList.Items)
{
if ($listItem.File -and $listItem.File.Name.ToLower().EndsWith(".xoml"))
{
Write-Host "Found Workflow: " $listItem.File.Name
$results += (CheckWorkflowFile $listItem.File)
}
}
}
return $results
}
function CheckWorkflowsForSite
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[Microsoft.SharePoint.SPSite]$SPSite,
[switch]$IgnoreSubSites
)
$results = @()
if ($IgnoreSubSites)
{
$SPWeb = $SPSite.RootWeb
$results += CheckWorkflowsForWeb $SPWeb
$SPWeb.Dispose()
}
else
{
foreach ($SPWeb in $SPSite.AllWebs)
{
$results += CheckWorkflowsForWeb $SPWeb
$SPWeb.Dispose()
}
}
return $results
}
if ([string]::IsNullOrEmpty($SiteCollectionUrl))
{
$SiteCollectionUrl = Read-Host "Please provide a site collection URL (Default: http://sharepoint)"
if ([String]::IsNullOrEmpty($SiteCollectionUrl))
{
$SiteCollectionUrl = "http://sharepoint"
}
}
$SPSite = Get-SPSite $SiteCollectionUrl -ErrorAction SilentlyContinue
if ($null -eq $SPSite)
{
Write-Host "Site collection $SiteCollectionUrl not found." -ForegroundColor Red
return;
}
$results = CheckWorkflowsForSite $SPSite
# Dispose of the Site
$SPSite.Dispose()
# Results can be exported to a CSV or manipulated
$results
變更歷程記錄
下表摘要說明本主題的一些最重要變更。
日期 |
描述 |
---|---|
2022 年 11 月 22 日 |
在「原因」區段中新增了備註,並使用 PowerShell 指令碼更新「因應措施」區段,以掃描工作流程 .xoml 檔案。 |