Skip to content

Instantly share code, notes, and snippets.

@joerodgers
Last active January 4, 2023 13:36
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save joerodgers/2302b394796c865818839d843bae2dad to your computer and use it in GitHub Desktop.
Save joerodgers/2302b394796c865818839d843bae2dad to your computer and use it in GitHub Desktop.
Adds the necessary authorizedType elements in the WEB.CONFIG and OWSTIMER.EXE.CONFIG on SharePoint servers
<#
This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment.
THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
We grant you a nonexclusive, royalty-free right to use and modify the sample code and to reproduce and distribute the object
code form of the Sample Code, provided that you agree:
(i) to not use our name, logo, or trademarks to market your software product in which the sample code is embedded;
(ii) to include a valid copyright notice on your software product in which the sample code is embedded; and
(iii) to indemnify, hold harmless, and defend us and our suppliers from and against any claims or lawsuits, including
attorneys' fees, that arise or result from the use or distribution of the sample code.
Please note: None of the conditions outlined in the disclaimer above will supercede the terms and conditions contained within
the Premier Customer Services Description.
----------------------------------------------------------
History
----------------------------------------------------------
10/15/2018 - Added three additional authorized types
09/18/2018 - Added an update to allow customers using Nintex to use the new IncludeNintexWorkflow switch to automatically add
the necessary authorizedType required for Nintex
09/17/2018 - Updated to match "final update" post
REFERENCE:
https://support.microsoft.com/en-us/help/4465015/sharepoint-workflows-stop-after-cve-2018-8421-security-update
https://blogs.msdn.microsoft.com/rodneyviana/2018/09/13/after-installing-net-security-patches-to-address-cve-2018-8421-sharepoint-workflows-stop-working/
https://blogs.msdn.microsoft.com/rodneyviana/2018/10/12/step-by-step-video-on-how-to-fix-the-sharepoint-workflow/
SUMMARY:
This script leverages the native SharePoint SPWebConfigModification API to deploy new updates to the web.config file for
each web application on each server in the farm. Servers added a later date will also get the updates applied because the API
configuration is persisted in the config database. This API does not update the web.config for the central administration web application.
If you are running workflows on the central admin web application, you will need to manually update the web.config using the steps in the
referenced blog.
==============================================================
#>
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | Out-Null
function Add-CodeDomAuthorizedType
{
<#
.Synopsis
Adds the necessary authorizedType elements to all web.config files for all non-central admin web applications
.DESCRIPTION
Adds the necessary authorizedType elements to all web.config files for all non-central admin web applications
.EXAMPLE
Add-CodeDomAuthorizedType
.EXAMPLE
Add-CodeDomAuthorizedType -IncludeNintexWorkflow
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$false)][switch]$IncludeNintexWorkflow
)
begin
{
$updateRequired = $false
$farmMajorVersion = (Get-SPFarm -Verbose:$false ).BuildVersion.Major
$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$authorizedTypes = @()
if( $farmMajorVersion -le 14)
{
$systemAssemblyVersion = "2.0.0.0"
$targetParentPath = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes"
}
else
{
$systemAssemblyVersion = "4.0.0.0"
$targetParentPath = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes/targetFx[@version='v4.0']"
}
if($IncludeNintexWorkflow.IsPresent)
{
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeTypeReferenceExpression"
}
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeBinaryOperatorExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodePrimitiveExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeMethodInvokeExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeMethodReferenceExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeFieldReferenceExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeThisReferenceExpression"
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodePropertyReferenceExpression"
}
# added 10/15/2018 to match Nov 2018 CU
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleDefinitions"
}
# added 10/15/2018 to match Nov 2018 CU
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleExpressionCondition"
}
# this should exist in web.config already
#$authorizedTypes += New-Object PSCustomObject -Property @{
# Assembly = "Microsoft.SharePoint.WorkflowActions, Version=$farmMajorVersion.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
# Namespace = "Microsoft.SharePoint.WorkflowActions"
# TypeName = "*"
#}
}
process
{
foreach( $authorizedType in $authorizedTypes )
{
$netFrameworkConfig = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$netFrameworkConfig.Path = $targetParentPath
$netFrameworkConfig.Name = "authorizedType[@Assembly='$($authorizedType.Assembly)'][@Namespace='$($authorizedType.Namespace)'][@TypeName='$($authorizedType.TypeName)'][@Authorized='True']"
$netFrameworkConfig.Owner = "NetFrameworkAuthorizedTypeUpdate"
$netFrameworkConfig.Sequence = 0
$netFrameworkConfig.Type = [Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType]::EnsureChildNode
$netFrameworkConfig.Value = "<authorizedType Assembly=`"$($authorizedType.Assembly)`" Namespace=`"$($authorizedType.Namespace)`" TypeName=`"$($authorizedType.TypeName)`" Authorized=`"True`"/>"
if( -not ($contentService.WebConfigModifications | ? { $_.Value -eq $netFrameworkConfig.Value }) )
{
Write-Verbose "Adding Authorized Type: $($netFrameworkConfig.Value)"
$contentService.WebConfigModifications.Add($netFrameworkConfig);
$updateRequired = $true
}
else
{
Write-Verbose "Authorized Type Exists: $($netFrameworkConfig.Value)"
}
}
if( $updateRequired )
{
Write-Verbose "Updating web.configs"
$contentService.Update()
$contentService.ApplyWebConfigModifications();
}
}
end
{
}
}
function Remove-CodeDomAuthorizedType
{
<#
.Synopsis
Removes any web configuration entires owned by "NetFrameworkAuthorizedTypeUpdate"
.DESCRIPTION
Removes any web configuration entires owned by "NetFrameworkAuthorizedTypeUpdate"
.EXAMPLE
Remove-CodeDomAuthorizedType
#>
[CmdletBinding()]
param()
begin
{
$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
}
process
{
$webConfigModifications = @($contentService.WebConfigModifications | ? { $_.Owner -eq "NetFrameworkAuthorizedTypeUpdate" })
foreach ( $webConfigModification in $webConfigModifications )
{
Write-Verbose "Found instance owned by NetFrameworkAuthorizedTypeUpdate"
$contentService.WebConfigModifications.Remove( $webConfigModification ) | Out-Null
}
if( $webConfigModifications.Count -gt 0 )
{
$contentService.Update()
$contentService.ApplyWebConfigModifications()
}
}
end
{
}
}
# will get the timerjob responsible for the web.config change deployment
# Get-SPTimerJob | ? { $_.Name -eq "job-webconfig-modification" }
# adds the updates to the farm, only needs to be run once per farm.
Add-CodeDomAuthorizedType -Verbose
# remove # below if you need to remove the web.config updates, you can with this function to retract the changes
# Remove-CodeDomAuthorizedType -Verbose
<#
This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment.
THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
We grant you a nonexclusive, royalty-free right to use and modify the sample code and to reproduce and distribute the object
code form of the Sample Code, provided that you agree:
(i) to not use our name, logo, or trademarks to market your software product in which the sample code is embedded;
(ii) to include a valid copyright notice on your software product in which the sample code is embedded; and
(iii) to indemnify, hold harmless, and defend us and our suppliers from and against any claims or lawsuits, including
attorneys' fees, that arise or result from the use or distribution of the sample code.
Please note: None of the conditions outlined in the disclaimer above will supercede the terms and conditions contained within
the Premier Customer Services Description.
----------------------------------------------------------
History
----------------------------------------------------------
03/27/2019 - Added all default authorized types from a default web.config on SharePoint 2010 farms
03/27/2019 - Added all default authorized rule types from a default web.config on SharePoint 2010 farms
10/15/2018 - Added three additional authorized types
09/20/2018 - Updated to automatically restart the timer service if any changes are made to the .config
09/18/2018 - Updated to add the necessary <configSections> section, if it doesn't exist in the existing owstimer.exe.config file.
09/18/2018 - Added an update to allow customers using Nintex to use the new IncludeNintexWorkflow switch to automatically add
the necessary authorizedType required for Nintex
09/17/2018 - Created script to update owstimer.exe.config file on farm servers.
REFERENCE:
https://blogs.msdn.microsoft.com/rodneyviana/2018/09/13/after-installing-net-security-patches-to-address-cve-2018-8421-sharepoint-workflows-stop-working/
SUMMARY:
This script will update each of the specified servers defined at the bottom of the script. If additional servers are added to the
farm at a later date, this script will need to be run against the new server(s) in order for the updates to be added to the owstimer.exe.config
==============================================================
#>
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | Out-Null
function Add-ConfigSections
{
<#
.Synopsis
Adds the necessary configSections if not already present in owstimer.exe.config
.DESCRIPTION
Adds the necessary configSections if not already present in owstimer.exe.config
.EXAMPLE
Add-ConfigSections -XmlDocument $xmlDoc
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][System.Xml.XmlDocument]$XmlDocument
)
begin
{
$farmMajorVersion = (Get-SPFarm -Verbose:$false ).BuildVersion.Major
}
process
{
if( $farmMajorVersion -le 14)
{
$sectionGroup = New-Object PSObject -Property @{
Path = "/configuration/configSections"
Name = "/configuration/configSections/sectionGroup[@name='System.Workflow.ComponentModel.WorkflowCompiler'][@type='System.Workflow.ComponentModel.Compiler.WorkflowCompilerConfigurationSectionGroup, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<sectionGroup name="System.Workflow.ComponentModel.WorkflowCompiler" type="System.Workflow.ComponentModel.Compiler.WorkflowCompilerConfigurationSectionGroup, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
$authorizedTypesSection = New-Object PSObject -Property @{
Path = "configuration/configSections/sectionGroup"
Name = "configuration/configSections/sectionGroup/section[@name='authorizedTypes'][@type='System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<section name="authorizedTypes" type="System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
$authorizedRuleTypesSection = New-Object PSObject -Property @{
Path = "configuration/configSections/sectionGroup"
Name = "configuration/configSections/sectionGroup/section[@name='authorizedRuleTypes'][@type='System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<section name="authorizedRuleTypes" type="System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
}
else
{
$sectionGroup = New-Object PSObject -Property @{
Path = "/configuration/configSections"
Name = "/configuration/configSections/sectionGroup[@name='System.Workflow.ComponentModel.WorkflowCompiler'][@type='System.Workflow.ComponentModel.Compiler.WorkflowCompilerConfigurationSectionGroup, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<sectionGroup name="System.Workflow.ComponentModel.WorkflowCompiler" type="System.Workflow.ComponentModel.Compiler.WorkflowCompilerConfigurationSectionGroup, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
$authorizedTypesSection = New-Object PSObject -Property @{
Path = "configuration/configSections/sectionGroup"
Name = "configuration/configSections/sectionGroup/section[@name='authorizedTypes'][@type='System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<section name="authorizedTypes" type="System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
$authorizedRuleTypesSection = New-Object PSObject -Property @{
Path = "configuration/configSections/sectionGroup"
Name = "configuration/configSections/sectionGroup/section[@name='authorizedRuleTypes'][@type='System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35']"
Value = '<section name="authorizedRuleTypes" type="System.Workflow.ComponentModel.Compiler.AuthorizedTypesSectionHandler, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />'
}
}
# ensure /configuration
if( -not ($XmlDocument | Select-Xml -XPath "configuration").Node )
{
Initialize-Path -XmlDocument $XmlDocument -Path "configuration" | Out-Null
}
# ensure /configuration/configSections. It must be the first child element of the <configuration> element.
if( -not ($XmlDocument | Select-Xml -XPath "/configuration/configSections").Node )
{
$configNode = ($XmlDocument | Select-Xml -XPath "configuration").Node
$configNode.InsertBefore( $XmlDocument.CreateElement("configSections"), $configNode.FirstChild) | Out-Null
}
# ensure /configuration/configSections/sectionGroup
if( -not ($XmlDocument | Select-Xml -XPath $sectionGroup.Name) )
{
$parentNode = ($XmlDocument | Select-Xml -XPath $sectionGroup.Path).Node
$parentNode.InnerXml += $sectionGroup.Value
}
# ensure /configuration/configSections/sectionGroup/section[@name='authorizedTypes']
if( -not ($XmlDocument | Select-Xml -XPath $authorizedTypesSection.Name) )
{
$parentNode = ($XmlDocument | Select-Xml -XPath $authorizedTypesSection.Path).Node
$parentNode.InnerXml += $authorizedTypesSection.Value
}
# ensure configuration/configSections/sectionGroup/section[@name='authorizedRuleTypes']
if( -not ($XmlDocument | Select-Xml -XPath $authorizedRuleTypesSection.Name) )
{
$parentNode = ($XmlDocument | Select-Xml -XPath $authorizedRuleTypesSection.Path).Node
$parentNode.InnerXml += $authorizedRuleTypesSection.Value
}
}
end
{
}
}
function Add-AuthorizedTypes
{
<#
.Synopsis
Adds the necessary authorizedTypes elements if not already present in owstimer.exe.config
.DESCRIPTION
Adds the necessary elements if not already present in owstimer.exe.config. Includes -IncludeNintexWorkflow
if the local farm utilizes Nintex workflows.
.EXAMPLE
Add-AuthorizedTypes -XmlDocument $xmlDoc
.EXAMPLE
Add-AuthorizedTypes -XmlDocument $xmlDoc -IncludeNintexWorkflow
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][System.Xml.XmlDocument]$XmlDocument,
[parameter(Mandatory=$false)][switch]$IncludeNintexWorkflow
)
begin
{
$authorizedTypes = @()
$farmMajorVersion = (Get-SPFarm -Verbose:$false ).BuildVersion.Major
if( $farmMajorVersion -le 14)
{
$systemAssemblyVersion = "2.0.0.0"
$targetParentPath = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes"
}
else
{
$systemAssemblyVersion = "4.0.0.0"
$targetParentPath = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes/targetFx[@version='v4.0']"
}
if($IncludeNintexWorkflow.IsPresent)
{
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeTypeReferenceExpression"
Authorized = $true
}
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeBinaryOperatorExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodePrimitiveExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeMethodInvokeExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeMethodReferenceExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeFieldReferenceExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodeThisReferenceExpression"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.CodeDom"
TypeName = "CodePropertyReferenceExpression"
Authorized = $true
}
# added 10/15/2018 to match Nov 2018 CU
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleDefinitions"
Authorized = $true
}
# added 10/15/2018 to match Nov 2018 CU
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=$systemAssemblyVersion, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleExpressionCondition"
Authorized = $true
}
# added 03/28/2019 to resolve other workflow init scenarios in SharePoint 2010 farms
if( $farmMajorVersion -eq 14 )
{
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "*"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "WhileActivity"
Authorized = $false
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "ConditionedActivityGroup"
Authorized = $false
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "ReplicatorActivity"
Authorized = $false
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "*"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.*"
TypeName = "WorkflowCompiler"
Authorized = $false
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Runtime"
TypeName = "CorrelationToken"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "Guid"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "DateTime"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "Boolean"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "Double"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "String"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Collections"
TypeName = "Hashtable"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Collections"
TypeName = "ArrayList"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Diagnostics"
TypeName = "DebuggableAttribute"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Runtime.CompilerServices"
TypeName = "CompilationRelaxationsAttribute"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Runtime.CompilerServices"
TypeName = "RuntimeCompatibilityAttribute"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "Int32"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System"
TypeName = "TimeSpan"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Collections.ObjectModel"
TypeName = "Collection``1"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.Workflow"
TypeName = "SPWorkflowActivationProperties"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.Workflow"
TypeName = "SPWorkflowTaskProperties"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.Workflow"
TypeName = "SPWorkflowHistoryEventType"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.Workflow"
TypeName = "SPItemKey"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.Workflow"
TypeName = "SPWorkflowUserContext"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint.WorkflowActions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.WorkflowActions"
TypeName = "*"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleDefinitions"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace = "System.Workflow.Activities.Rules"
TypeName = "RuleExpressionCondition"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.Office.Access.Server.Application, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.Office.Access.Server.Macro.Runtime"
TypeName = "*"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.Office.Access.Server.Application, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.Office.Access.Server.Quickflow.Runtime"
TypeName = "*"
Authorized = $true
}
$authorizedTypes += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.Office.Workflow.Actions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.Office.Workflow.Actions"
TypeName = "*"
Authorized = $true
}
}
}
process
{
Initialize-Path -XmlDocument $XmlDocument -Path "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes" | Out-Null
if( $farmMajorVersion -gt 14 -and -not $XmlDocument.SelectSingleNode( "/configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes/targetFx[@version='v4.0']" ))
{
$parent = $XmlDocument.SelectSingleNode( "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes")
$parent.InnerXml += "<targetFx version=`"v4.0`" />"
}
foreach( $authorizedType in $authorizedTypes )
{
$object = New-Object PSObject -Property @{
Path = $targetParentPath
Name = "authorizedType[@Assembly='$($authorizedType.Assembly)'][@Namespace='$($authorizedType.Namespace)'][@TypeName='$($authorizedType.TypeName)'][@Authorized='$($authorizedType.Authorized)']"
Value = "<authorizedType Assembly=`"$($authorizedType.Assembly)`" Namespace=`"$($authorizedType.Namespace)`" TypeName=`"$($authorizedType.TypeName)`" Authorized=`"$($authorizedType.Authorized)`"/>"
}
$parentNode = $XmlDocument.SelectSingleNode( $object.Path )
if( $parentNode -and -not $parentNode.SelectSingleNode( $object.Name ))
{
Write-Verbose -Message "Adding Authorized Type: $($object.Value)"
$parentNode.InnerXml += $object.Value
}
}
}
end
{
}
}
function Add-AuthorizedRules
{
<#
.Synopsis
Adds the necessary authorizedTypes elements under the authorizedRuleTypes element if not already present in owstimer.exe.config
.DESCRIPTION
Adds the necessary elements if not already present in owstimer.exe.config.
.EXAMPLE
Add-AuthorizedRules -XmlDocument $xmlDoc
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][System.Xml.XmlDocument]$XmlDocument
)
begin
{
$farmMajorVersion = (Get-SPFarm -Verbose:$false ).BuildVersion.Major
$targetParentPath = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedRuleTypes"
$authorizedRules = @()
$authorizedRules += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.Office.Access.Server.Application, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.Office.Access.Server.Quickflow.Runtime"
TypeName = "*"
Authorized = $true
}
$authorizedRules += New-Object PSCustomObject -Property @{
Assembly = "Microsoft.SharePoint.WorkflowActions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace = "Microsoft.SharePoint.WorkflowActions"
TypeName = "WorkflowCodeTypeReferenceExpression"
Authorized = $true
}
$authorizedRules += New-Object PSCustomObject -Property @{
Assembly = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Namespace = "System.Runtime.CompilerServices"
TypeName = "ExtensionAttribute"
Authorized = $true
}
}
process
{
# only make the updates to 2010 farms.
if( $farmMajorVersion -eq 14 )
{
Initialize-Path -XmlDocument $XmlDocument -Path "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedRuleTypes" | Out-Null
foreach( $authorizedRule in $authorizedRules )
{
$object = New-Object PSObject -Property @{
Path = $targetParentPath
Name = "authorizedType[@Assembly='$($authorizedRule.Assembly)'][@Namespace='$($authorizedRule.Namespace)'][@TypeName='$($authorizedRule.TypeName)'][@Authorized='$($authorizedRule.Authorized)']"
Value = "<authorizedType Assembly=`"$($authorizedRule.Assembly)`" Namespace=`"$($authorizedRule.Namespace)`" TypeName=`"$($authorizedRule.TypeName)`" Authorized=`"$($authorizedRule.Authorized)`"/>"
}
$parentNode = $XmlDocument.SelectSingleNode( $object.Path )
if( $parentNode -and -not $parentNode.SelectSingleNode( $object.Name ))
{
Write-Verbose -Message "Adding Authorized Rule: $($object.Value)"
$parentNode.InnerXml += $object.Value
}
}
}
}
end
{
}
}
function Initialize-Path
{
<#
.Synopsis
Ensures the supplied XML node path has been created.
.DESCRIPTION
Ensures the supplied XML node path has been created in the supplied in the XMLDocument
.EXAMPLE
Initialize-Path -XmlDocument $xml -Path "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes"
.EXAMPLE
Initialize-Path -XmlDocument $xml -Path "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes/targetFx"
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][System.Xml.XmlDocument]$XmlDocument,
[parameter(Mandatory=$true)][string]$Path
)
begin
{
$farmMajorVersion = (Get-SPFarm -Verbose:$false ).BuildVersion.Major
}
process
{
$currentNode = $XmlDocument
foreach( $nodeName in $Path -split "/" )
{
$node = $currentNode.SelectSingleNode( $nodeName )
if( -not $node )
{
$node = $currentNode.AppendChild($XmlDocument.CreateElement($nodeName))
}
$currentNode = $node
}
return $currentNode
}
end
{
}
}
function Add-CodeDomAuthorizedTypeToOWSTimerConfig
{
<#
.Synopsis
Adds the necessary updates to the OWSTIMER.EXE.CONFIG file on the supplied computers.
.DESCRIPTION
Adds the necessary updates to the OWSTIMER.EXE.CONFIG file on the supplied computers. Any existing OWSTIMER.EXE.CONFIG files
will be backed to a timestamped file.
.EXAMPLE
Add-CodeDomAuthorizedTypeToOWSTimerConfig -ComputerName "Computer01", "Computer02"
.EXAMPLE
Add-CodeDomAuthorizedTypeToOWSTimerConfig -ComputerName "Computer01", "Computer02" -IncludeNintexWorkflow
#>
[CmdletBinding()]
param
(
[parameter(Mandatory=$true)][string[]]$ComputerName,
[parameter(Mandatory=$false)][switch]$IncludeNintexWorkflow
)
begin
{
}
process
{
foreach( $computer in $ComputerName )
{
# get the path to owstimer.exe on each $ComputerName, just in case it's not in the expected location
$timerServiceConfigPath = Get-WmiObject -Query "SELECT * FROM Win32_Service WHERE name = 'SPTimerV4'" -ComputerName $computer | SELECT @{Name="PathName"; Expression={$_.PathName.Trim('"')}}
Write-Verbose -Message "Processing server: $($computer)"
# convert local path to UNC PATH
$uncPath = "\\$computer\$($timerServiceConfigPath.PathName)" -replace ":", "$"
$fi = New-Object System.IO.FileInfo( $uncPath )
# make sure the path exists
if( -not $fi.Directory.Exists )
{
Write-Error -Message "Directory not found: $($fi.Directory.FullName)"
continue
}
# add ".config" to the end of the file name
$uncPath = "$uncPath.CONFIG"
# create a default owstimer.exe.config, if none exists
if( -not (Test-Path -Path $uncPath -PathType Leaf) )
{
# build a base XML file based on what 2010 would have
$defaultXml = New-Object System.Text.StringBuilder
$defaultXml.AppendLine("<?xml version=`"1.0`" encoding=`"utf-8`" ?>") | Out-Null
$defaultXml.AppendLine("<configuration>") | Out-Null
$defaultXml.AppendLine("<runtime>") | Out-Null
$defaultXml.AppendLine("</runtime>") | Out-Null
$defaultXml.AppendLine("</configuration>") | Out-Null
$defaultXml.ToString() | Set-Content -Path $uncPath
}
# make a backup of the file before doing anything
Get-Content -Path $uncPath | Set-Content -Path "$($uncPath)_backup_$(Get-Date -Format 'yyyy_MM_dd_hh.mm.ss').config"
# get the existing xml from the file
[xml]$xml = Get-Content -Path $uncPath
$originalXml = $xml.OuterXml
# ensure the necessary config sections are present
Add-ConfigSections -XmlDocument $xml
# ensure authorizedTypes are added
Add-AuthorizedTypes -XmlDocument $xml -IncludeNintexWorkflow:$IncludeNintexWorkflow.IsPresent
# Added: 03/27/2019 - ensure authorizedRuleTypes are added
Add-AuthorizedRules -XmlDocument $xml
if( $originalXml -ne $xml.OuterXml )
{
Write-Verbose -Message "Saving file changes on $computer"
# save the changes
$xml.Save($uncPath)
# restart the timer service to pick up the changes
Get-Service -Name SPTimerV4 -ComputerName $computer | Restart-Service
}
}
}
end
{
}
}
# get all the servers in the farm
$serverNames = @(Get-SPServer | ? { $_.Role -ne "Invalid" } | Select -ExpandProperty Name)
# add the owstimer.exe.config updates to all the servers. Add the -IncludeNintexWorkflow if you use Nintex workflows on the farm
Add-CodeDomAuthorizedTypeToOWSTimerConfig -ComputerName $serverNames -Verbose
@nigelhertz
Copy link

Hi, I just wanted to let you know that I had to uncomment the section "# added 10/15/2018 - TBD if necessary" where it allows all workflow actions for a client using SP2010, as all their workflows with pauses were still failing.

@fredericklin
Copy link

@joerogers We attempted the fix for owstimer.exe.config again; This time it worked when uncommenting the "# added 10/15/2018 - TBD if necessary" section. Without this, Nintex workflow workloads would be moved to owstimer and just simply stop working. Even when we made the config change, the stalled workflows did not recover. We had to terminate and re-run the impacted workflows. I suggest moving the commented code to the $IncludeNintexWorkflow.IsPresent conditional statement.

@nigelhertz thanks for mentioning this!

@kdx-perbol
Copy link

kdx-perbol commented Nov 1, 2018

A little gotcha; I ran it like this:

PS C:\> .\Add-CodeDomAuthorizedTypeToOWSTimerConfig.ps1 -IncludeNintexWorkflow

I don't think the switch is actually applied here since that's not how you pass switches to PS cmdlets... or? Either way, no CodeTypeReferenceExpression reference added.

@eddiewong396
Copy link

Can somebody assist me in running this? I did run the script but it didn't change anything. Do I run the Add-CodeDomAuthorizedTypeToOWSTimerConfig.ps1 first or Add-CodeDomAuthorizedType.ps1? And do I run IISRESET after? Thanks

@LauraBlack
Copy link

Hi,
I followed the video instruction to make the change for Nintex but I'm getting an error while running it. See below:
image

I've also attached the script I used. Did I do something wrong? Do I need to include a different switch when running it w/ the Nintex change?

add-codedomauthorizedtype_page_1
add-codedomauthorizedtype_page_2
add-codedomauthorizedtype_page_3
add-codedomauthorizedtype_page_4
add-codedomauthorizedtype_page_5
add-codedomauthorizedtype_page_6
add-codedomauthorizedtype_page_7

@kefujino
Copy link

kefujino commented Nov 29, 2018

@LauraBlack

Error message says, missing closing '}' in function of Remove-CodeDomAuthorizedType.
Seemingly there is no '}' in the process statement. (Line 194)
I think that it will work, you add closing '}' in line 228.

process
   {
       $webConfigModifications = @($contentService.WebConfigModifications | ? { $_.Owner -eq "NetFrameworkAuthorizedTypeUpdate" })

       foreach ( $webConfigModification in $webConfigModifications ) 
       {
           Write-Verbose "Found instance owned by NetFrameworkAuthorizedTypeUpdate"
           $contentService.WebConfigModifications.Remove( $webConfigModification ) | Out-Null
       }
       
       if( $webConfigModifications.Count -gt 0 )
       {
           $contentService.Update()
           $contentService.ApplyWebConfigModifications()

       } 
   }#<-- Need one more closing '}'
   end
   {
   }    
}

@evlo
Copy link

evlo commented Apr 5, 2022

I did run Add-CodeDomAuthorizedTypeToOWSTimerConfig on affected server where the timer is used for running workflows, restarted sharepoint timer service and error is still happening. I have verified it did changes to C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\BIN\OWSTIMER.EXE.CONFIG and explicitly listed types etc.
Only difference I can see from ms article is
<targetFx version="v4.0">
vs
<targetFx>
any tips where to look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment