Skip to content

Instantly share code, notes, and snippets.

@1RedOne
Forked from wpsmith/Enable-SPCORS.ps1
Last active August 29, 2015 14:20
Show Gist options
  • Save 1RedOne/9f09bc2a467a4f291cfb to your computer and use it in GitHub Desktop.
Save 1RedOne/9f09bc2a467a4f291cfb to your computer and use it in GitHub Desktop.
<#
.Synopsis
Modifies the web.config file for all servers for specific SharePoint web application.
.Description
Modifies the web.config file for all servers for specific SharePoint web application.
.Example
Add-SPCORSOrigin -Url http://domain.com
.Example
Add-SPCORSOrigin (Get-SPWebApplication http://domain.com)
.Notes
Name: SP-EnableCORS
Author: Travis Smith
LastEdit: 05/05/2014
#>
# Adds SharePoint Snapin if needed and returns bool based on whether the Snapin was added.
Function Add-SPCORSSnapin {
[CmdletBinding()]
param()
$SPSnapinAdded = $false;
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
$SPSnapinAdded = $true;
Write-Host "Need SharePoint Snapin. Adding SP Snapin"
Add-PSSnapin -Name Microsoft.SharePoint.PowerShell
#Wait until web.config modifications finished by timer job
while( (Get-SPTimerJob | ? { $_.Name -eq "job-add-snapin"}) -ne $null ) {
Write-Host "." -NoNewline
Start-Sleep 1
}
}
else
{
Write-Host "SharePoint Snapin already added."
}
Return $SPSnapinAdded
}
# Removes SharePoint Snapin
Function Remove-SPCORSSnapin
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true, Position = 0)]
[System.Boolean]
[Alias('SnapinAdded')]
$SPSnapinAdded
)
if ( $SPSnapinAdded )
{
Write-Host "Removing SharePoint Snapin."
Remove-PSSnapin -Name Microsoft.SharePoint.PowerShell
}
}
# Removes SPCORS WebConfig Modifications from Web Application
Function Remove-SPCORSWebMods
{
[CmdletBinding()]
Param
(
[Parameter(
Mandatory = $true,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
$WebApplication,
[Parameter(Mandatory = $false, Position = 1)]
[System.String]
[Alias('Owner')]
$webModOwner
)
BEGIN {
$SPSnapinAdded = Add-SPCORSSnapin
}
PROCESS {
$webApp = $WebApplication.Read()
if (!$webModOwner)
{
$webModOwner = "CrossSiteScripting"
}
Write-Host "Removing CORS $webModOwner modifications..." -ForegroundColor Magenta
$oldMods = @();
$webApp.WebConfigModifications | ? { $_.Owner -eq $webModOwner } | % {
$oldMods = $oldMods + $_
}
if ($oldMods)
{
Write-Host "Found CORS modifications..." -ForegroundColor Magenta
$oldMods | % {
$webApp.WebConfigModifications.Remove($_)
}
#update
Write-Host "Updating WebConfigModifications $webModOwner removal..." -ForegroundColor Green
# update the Web Application and apply all existing web.config modifications - this executes the "remove" actions from above
Update-SPCORSWebApp $webApp
#$webApp.Parent.ApplyWebConfigModifications()
#$webApp.Update()
}
else
{
Write-Host "No CORS WebConfigModifications found." -ForegroundColor Yellow
}
}
END {
Remove-SPCORSSnapin $SPSnapinAdded
}
}
# Private Function
# Updates a Web Application with SP WebConfig Modification & waits until update is completed
Function Update-SPCORSWebApp
{
[CmdletBinding()]
param(
[Parameter(
Mandatory = $true,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
$WebApplication
)
PROCESS {
$debugMessage=@"
Previously when running this tool, we had an error on line 147, within the Update-SPCorsWebApp Function.
This is likely caused by the `$webapp the .Update() method not existing on this object.
Troubleshooting:
- Ensure the needed binaries are installed to instantiate a [Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind] object
- Ensure that $webApp exists
"@
$webApp = $WebApplication.Read()
Write-Host "Web Application $($webApp.DisplayName) updating..."
Write-debug $debugMessage
$webApp.Update()
$webApp.Parent.ApplyWebConfigModifications()
#[Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplyWebConfigModifications()
Write-Host "Web Application $($webApp.DisplayName) updated"
Wait-SPCORS
}
}
# Private Function
# Waits until Job with specific name (defaults to "job-webconfig-modification") is completed.
Function Wait-SPCORS
{
[CmdletBinding()]
param(
[Parameter(
Mandatory = $false,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
[Alias('Job')]
$jobName
)
BEGIN {
if (!$jobName)
{
$jobName = "job-webconfig-modification"
}
}
PROCESS {
#Wait until web.config modifications finished by timer job
while( (Get-SPTimerJob | ? { $_.Name -eq $jobName}) -ne $null ) {
Write-Host "." -NoNewline
Start-Sleep 1
}
}
}
# Adds Cross-Site Scripting Origin WebConfig Modification
Function Add-SPCORSOrigin
{
[CmdletBinding()]
param(
[Parameter(
Mandatory = $false,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
$WebApplication,
[Parameter(
Mandatory = $false,
Position = 1,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Alias('Url')]
[System.String]
$siteUrl,
[Parameter(
Mandatory = $false,
Position = 2,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[System.String]
$origin
)
BEGIN {
$SPSnapinAdded = Add-SPCORSSnapin
If ($WebApplication) {
Write-Verbose "Reading Web Application"
$webApp = $WebApplication.Read()
}
Else
{
Write-Verbose "Getting Web Application by SiteUrl"
If (!$siteUrl) {
$siteUrl = Read-Host "Enter the URL of the Web Application"
}
$site = Get-SPSite $siteUrl
$webApp = $site.WebApplication
}
}
PROCESS {
# Remove old web.config modifications of MyAuthenticationProvider
#Remove-SPCORSWebMods (Reference-Variable -Name webApp -Verbose) -Owner "CrossSiteScriptingOrigin"
# New web.config modifications for MyAuthenticationProvider
$mod = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$mod.Name = "add[@destination='$webApp.Url'][@name='Access-Control-Allow-Origin'][@value='$origin']"
$mod.Sequence = 0
$mod.Owner = "CrossSiteScriptingOrigin"
## SPWebConfigModificationType.EnsureChildNode -> 0
## SPWebConfigModificationType.EnsureAttribute -> 1
## SPWebConfigModificationType.EnsureSection -> 2
#0 = for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$mod.Type = 0
$mod.Value = "<add name='Access-Control-Allow-Origin' value='$origin' />"
Write-Host "Adding $($mod.Value)..."
$webApp.WebConfigModifications.Add($mod)
# Update Web Application
Update-SPCORSWebApp $webApp
}
END {
Remove-SPCORSSnapin $SPSnapinAdded
}
}
# Adds Cross-Site Scripting Headers, Methods & Credentials
Function Add-SPCORS
{
[CmdletBinding()]
param(
[Parameter(
Mandatory = $false,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
$WebApplication,
[Parameter(
Mandatory = $false,
Position = 1,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Alias('Url')]
[System.String]
$siteUrl
)
BEGIN {
$SPSnapinAdded = Add-SPCORSSnapin
If ($WebApplication) {
Write-Verbose "Reading Web Application"
$webApp = $WebApplication.Read()
}
Else
{
Write-Verbose "Getting Web Application by SiteUrl"
If (!$siteUrl) {
$siteUrl = Read-Host "Enter the URL of the Web Application"
}
$site = Get-SPSite $siteUrl
$webApp = $site.WebApplication
}
}
PROCESS {
# Remove old web.config modifications of MyAuthenticationProvider
Remove-SPCORSWebApp $webApp
Write-Verbose "Adding Access-Control-Request-Method"
$mod1 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod1.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$mod1.Name = "add[@name='Access-Control-Request-Method'][@value='GET,POST,HEAD,OPTIONS']"
$mod1.Sequence = 0
$mod1.Owner = "CrossSiteScripting"
$mod1.Type = 0
$mod1.Value = "<add name='Access-Control-Request-Method' value='GET,POST,HEAD,OPTIONS' />"
$webapp.WebConfigModifications.Add($mod1)
Write-Verbose "Adding Access-Control-Request-Headers"
$mod2 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod2.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$mod2.Name = "add[@name='Access-Control-Request-Headers'][@value='Content-Type,Authorization']"
$mod2.Sequence = 0
$mod2.Owner = "CrossSiteScripting"
$mod2.Type = 0
$mod2.Value = "<add name='Access-Control-Request-Headers' value='Content-Type,Authorization' />"
$webapp.WebConfigModifications.Add($mod2)
Write-Verbose "Adding Access-Control-Request-Credentials"
$mod3 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod3.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$mod3.Name = "add[@name='Access-Control-Allow-Credentials'][@value='true']"
$mod3.Sequence = 0
$mod3.Owner = "CrossSiteScripting"
$mod3.Type = 0
$mod3.Value = "<add name='Access-Control-Allow-Credentials' value='true' />"
$webapp.WebConfigModifications.Add($mod3)
Update-SPCORSWebApp $webapp
}
END {
Remove-SPCORSSnapin $SPSnapinAdded
}
}
# Enables SPCORS by Adding Cross-Site Scripting Origin, Headers, Methods & Credentials
Function Enable-SPCORS
{
[CmdletBinding()]
param(
[Parameter(
Mandatory = $false,
Position = 0,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Alias('Url')]
[System.String]
$siteUrl,
[Parameter(
Mandatory = $false,
Position = 1,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind]
$WebApplication,
[Parameter(
Mandatory = $false,
Position = 2,
ValueFromPipeline = $true,
ValueFromPipelinebyPropertyName = $true)]
[System.String]
$origin
)
BEGIN {
$SPSnapinAdded = Add-SPCORSSnapin
If ($WebApplication) {
Write-Verbose "Reading Web Application"
$webApp = $WebApplication.Read()
}
Else
{
Write-Verbose "Getting Web Application by SiteUrl"
If (!$siteUrl) {
$siteUrl = Read-Host "Enter the URL of the Web Application"
}
$site = Get-SPSite $siteUrl
$webApp = $site.WebApplication
}
If (!$origin) {
$origin = "*";
}
}
PROCESS {
# Just in case...
Set-Variable -Name webApp -Value $webApp
Write-Verbose "Adding Origin CORS"
Add-SPCORSOrigin $webApp $origin
Write-Verbose "Adding Other CORS"
Add-SPCORS $webApp
}
END {
Remove-SPCORSSnapin $SPSnapinAdded
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment