증상
Microsoft SharePoint Server 다음 10월 보안 업데이트를 설치한 후 일부 Microsoft SharePoint 2010 워크플로 시나리오가 차단될 수 있습니다. 또한 '6ksbk' 이벤트 태그는 SharePoint ULS(통합 로깅 시스템) 로그에 기록됩니다.
원인
SharePoint 워크플로의 보안을 강화하기 위해 SharePoint는 이제 워크플로 .xoml 파일에 대해 UTF-8 문자 인코딩만 지원합니다.
참고: SharePoint Designer, Microsoft Visual Studio 및 Nintex와 같은 SharePoint 워크플로 도구는 기본적으로 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 파일을 검사했습니다. |