Skip to content

Instantly share code, notes, and snippets.

@tobiaswest
Last active March 26, 2020 18:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobiaswest/921d3d0ea8d63947b609 to your computer and use it in GitHub Desktop.
Save tobiaswest/921d3d0ea8d63947b609 to your computer and use it in GitHub Desktop.
Add-Type -Path "$pwd\lib\microsoft.sharepoint.client.dll"
Add-Type -Path "$pwd\lib\microsoft.sharepoint.client.runtime.dll"
Function AuthenticateToO365($site, $username, $password) {
if($site -eq $null)
{
$site = Read-Host "Please enter site name"
}
if($username -eq $null)
{
$username = Read-Host "Please enter username"
}
if($password -eq $null)
{
$password = Read-Host "Please enter password"
}
$securepassword = ConvertTo-SecureString $password -AsPlainText -Force
write-Host "Logging on as $username..." -ForegroundColor Yellow
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($site)
$creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securepassword)
$ctx.Credentials = $creds
if(!$ctx.ServerObjectIsNull.Value)
{
write-host "Connected to O365!!"
return $ctx
}
}
Function PublishContentType($ctx, $contentTypeID, $operation) {
$site = $ctx.Site
$ctx.Load($site)
$ctx.ExecuteQuery()
$ctPubPageUrl = $site.Url + "/_layouts/15/managectpublishing.aspx?ctype=$contentTypeID"
$cookieContainer = New-Object System.Net.CookieContainer
$request = $ctx.WebRequestExecutorFactory.CreateWebRequestExecutor($ctx, $ctPubPageUrl).WebRequest
if ($ctx.Credentials -ne $null)
{
$authCookieValue = $ctx.Credentials.GetAuthenticationCookie($ctx.Url)
# Create fed auth Cookie
$fedAuth = new-object System.Net.Cookie
$fedAuth.Name = "FedAuth"
$fedAuth.Value = $authCookieValue.TrimStart("SPOIDCRL=")
$fedAuth.Path = "/"
$fedAuth.Secure = $true
$fedAuth.HttpOnly = $true
$fedAuth.Domain = (New-Object System.Uri($ctx.Url)).Host
# Hookup authentication cookie to request
$cookieContainer.Add($fedAuth)
$request.CookieContainer = $cookieContainer
}
else
{
# No specific authentication required
$request.UseDefaultCredentials = $true
}
$request.ContentLength = 0
$response = $request.GetResponse()
# decode response
$strResponse = $null
$stream = $response.GetResponseStream()
if (-not([String]::IsNullOrEmpty($response.Headers["Content-Encoding"])))
{
if ($response.Headers["Content-Encoding"].ToLower().Contains("gzip"))
{
$stream = New-Object System.IO.Compression.GZipStream($stream, [System.IO.Compression.CompressionMode]::Decompress)
}
elseif ($response.Headers["Content-Encoding"].ToLower().Contains("deflate"))
{
$stream = new-Object System.IO.Compression.DeflateStream($stream, [System.IO.Compression.CompressionMode]::Decompress)
}
}
# get response string
$sr = New-Object System.IO.StreamReader($stream)
$strResponse = $sr.ReadToEnd()
$sr.Close()
$sr.Dispose()
$stream.Close()
$inputMatches = $strResponse | Select-String -AllMatches -Pattern "<input.+?\/??>" | select -Expand Matches
$inputs = @{}
# Look for inputs and add them to the dictionary for postback values
foreach ($match in $inputMatches)
{
#get the name of the input (i.e. the radio button's name)
if (-not($match[0] -imatch "name=\""(.+?)\"""))
{
continue
}
$name = $matches[1]
#get the value of the input (i.e. the radio button's value)
if(-not($match[0] -imatch "value=\""(.+?)\"""))
{
continue
}
$value = $matches[1]
#check whether option is disbaled or not
$disabled=$false
if($match[0] -imatch "disabled=\""(.+?)\""")
{
$disabled=$true
}
#if it's the operation radio button group and it matches the action
if($name -eq "ctl00`$PlaceHolderMain`$actionSection`$RadioGroupAction" -and $operation -eq $value)
{
if($disabled -eq $true)
{
if($operation -eq "publishButton")
{
#requested publish, it's already published so we'll just republish it
$inputs.Add($name, "republishButton")
write-Host "Publish Requested against content type already published...republishing content type instead" -ForegroundColor Yellow
}
elseif($operation -eq "unpublishButton")
{
#requested unpublish, it's not currently published, so do nothing
write-Host "Unpublish requested, content type not currently published so doing nothing" -ForegroundColor Yellow
continue
}
elseif($operation -eq "republishButton")
{
#requested republish, but it's currently not published, so we'll go ahead and publish it
$inputs.Add($name, "publishButton")
write-Host "Republish Requested against content type not already published...publishing content type" -ForegroundColor Yellow
}
}
#operation requested is valid based on current state
else
{
$inputs.Add($name, $value)
write-Host "...updating content type" -ForegroundColor Yellow
}
}
#if it's the operation radio button group and it doesn't match the action
elseif($name -eq "ctl00`$PlaceHolderMain`$actionSection`$RadioGroupAction" -and $operation -ne $value)
{
#do nothing
}
#otherwise, add the value
else
{
$inputs.Add($name, $value)
}
}
# Format inputs as postback data string, but ignore the one that ends with iidIOGoBack
$strPost = ""
foreach ($inputKey in $inputs.Keys)
{
if (-not([String]::IsNullOrEmpty($inputKey)) -and -not($inputKey.EndsWith("iidIOGoBack")))
{
$strPost += [System.Uri]::EscapeDataString($inputKey) + "=" + [System.Uri]::EscapeDataString($inputs[$inputKey]) + "&"
}
}
$strPost = $strPost.TrimEnd("&")
$postData = [System.Text.Encoding]::UTF8.GetBytes($strPost);
# Build postback request
$publishRequest = $ctx.WebRequestExecutorFactory.CreateWebRequestExecutor($ctx, $ctPubPageUrl).WebRequest
$publishRequest.Method = "POST"
$publishRequest.Accept = "text/html, application/xhtml+xml, */*"
if ($ctx.Credentials -ne $null)
{
$publishRequest.CookieContainer = $cookieContainer
}
else
{
# No specific authentication required
$publishRequest.UseDefaultCredentials = $true
}
$publishRequest.ContentType = "application/x-www-form-urlencoded"
$publishRequest.ContentLength = $postData.Length
$publishRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
$publishRequest.Headers["Cache-Control"] = "no-cache";
$publishRequest.Headers["Accept-Encoding"] = "gzip, deflate";
$publishRequest.Headers["Accept-Language"] = "fr-FR,en-US";
# Add postback data to the request stream
$stream = $publishRequest.GetRequestStream()
$stream.Write($postData, 0, $postData.Length)
$stream.Close();
$stream.Dispose()
# Perform the postback
$response = $publishRequest.GetResponse()
$response.Close()
$response.Dispose()
}
#authenticate user. null values are passed in for public facing script, prompts user for details.
$ctx = AuthenticateToO365 "https://[yourtenant].sharepoint.com/sites/contenttypehub" $null $null
$web = $ctx.Web
$ctx.Load($web)
$ctx.ExecuteQuery()
$contenttypes = $web.AvailableContentTypes
$ctx.Load($contenttypes)
$ctx.ExecuteQuery()
foreach($ct in $contenttypes)
{
if($ct.Group -eq "Custom Content Types")
{
#options are publishButton, republishButton and unpublishButton
PublishContentType $ctx $ct.Id "publishButton"
write-host $ct.Name "Published" -ForegroundColor Green
}
}
@victorcea87
Copy link

Hello, I'm trying to run it but it throws a 403 forbidden when it calls to the response of the request (line 75). Any ideas?

Thanks!

@JCSALGADOSINFIN
Copy link

Hi, I.m having the same issue as @victorcea87. I´d like to know if there is an idea about this. @victorcea87, did you find a solution?. Thanks!

@blair24
Copy link

blair24 commented Feb 22, 2019

Hey,

@victorcea87 @JCSALGADOSINFIN
Having the same issue as well, wondering if you managed to solve this?

@keccomoria
Copy link

keccomoria commented Mar 26, 2020

Hey,

@victorcea87 @JCSALGADOSINFIN
Having the same issue as well, wondering if you managed to solve this?

Hi @blair24,
I fixed the issue simply changing the cookie's name
$fedAuth.Name = "SPOIDCRL"
and now it's working
image

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