Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
#Variables for Web and Page URLs
$WebURL="http://somesite.company.com/sites/collection/subsite"
$OldPageLayoutName="OldPageLayout.aspx"
$NewPageLayoutName="NewPageLayout.aspx"
#Get the web and page
$Web = Get-SPWeb $WebURL
#Get Publishing Site and Web
$PublishingSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($Web.Site)
$PublishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
#Get New Page Layout
$SitePageLayouts = $PublishingSite.GetPageLayouts($false)
$NewPageLayout = $SitePageLayouts | ? {$_.Name -eq $NewPageLayoutName}
#Get Pages Library
$PublishingPages = $PublishingWeb.GetPublishingPages()
#Iterate throgh each page
foreach ($Page in $PublishingPages)
{
$Page.CheckOut()
$Page.Layout = $NewPageLayout
$Page.ListItem.Update();
$Page.CheckIn("Page layout Updated via PowerShell")
#$page.ListItem.File.Publish("")
if ($Page.ListItem.ParentList.EnableModeration)
{
$Page.ListItem.File.Approve("Publishing Page Layout Updated!");
}
write-host "Updated Page layout on: "$Page.url
}
$Web.Dispose()
Day to day Powershell, SharePoint, and Project Server experiences. Any scripts here are provided as-is, and you're encouraged to test them before you run them on production. Most are scripts I've altered to suit my needs, and come from places like Stack Overflow or TechNet.
Thursday, April 14, 2016
Monday, March 21, 2016
Powershell to remove all alerts for a user in a Web Application
This script will delete all alerts for a specific user on a Web App. It's useful when a user is deleted, but the MySite cleanup job did not remove their collection level alerts.
Credit on this one to: http://www.sharepointdiary.com/2011/11/managing-alerts-using-powershell.html - Salaudeen Rajack.
##### Remove all alerts for specific user from a Web Application #####
$SPwebApp = Get-SPWebApplication "http://somesharepointsite.com"
$SpecificUser = "AD\someuser"
foreach ($SPsite in $SPwebApp.Sites)
{ # get the collection of webs
foreach($SPweb in $SPsite.AllWebs)
{ $alerts = $SPweb.Alerts
# if 1 or more alerts for a particular user, Make a note of them by copying their ID to an Array
if ($alerts.Count -gt 0)
{ $myalerts = @()
foreach ($alert in $alerts)
{ if ($alert.User -like $SpecificUser)
{ $myalerts += $alert
}
} ### now we have alerts for this site, we can delete them
foreach ($alertdel in $myalerts)
{ $alerts.Delete($alertdel.ID)
write-host $alertdel.ID
}
}
}
}
Credit on this one to: http://www.sharepointdiary.com/2011/11/managing-alerts-using-powershell.html - Salaudeen Rajack.
##### Remove all alerts for specific user from a Web Application #####
$SPwebApp = Get-SPWebApplication "http://somesharepointsite.com"
$SpecificUser = "AD\someuser"
foreach ($SPsite in $SPwebApp.Sites)
{ # get the collection of webs
foreach($SPweb in $SPsite.AllWebs)
{ $alerts = $SPweb.Alerts
# if 1 or more alerts for a particular user, Make a note of them by copying their ID to an Array
if ($alerts.Count -gt 0)
{ $myalerts = @()
foreach ($alert in $alerts)
{ if ($alert.User -like $SpecificUser)
{ $myalerts += $alert
}
} ### now we have alerts for this site, we can delete them
foreach ($alertdel in $myalerts)
{ $alerts.Delete($alertdel.ID)
write-host $alertdel.ID
}
}
}
}
Friday, March 18, 2016
Powershell to approve all items in a SharePoint list
This script will set all items in the list to Approved. Handy if you've bulk updated a bunch of items than need to get them published.
add-pssnapin microsoft.sharepoint.powershell
#$site = new-object Microsoft.SharePoint.SPSite("http://somesite.com/news")
$web = get-spweb "http://somesite.com/news/2016/"
$list = $web.Lists["Pages to be Changed"]
$items = $list.Items
foreach ($item in $items)
{
$item["_ModerationStatus"] = 0
$item.Update()
}
Remove WWW prefix from SharePoint URLs
It's not every day you are tasked with doing something, with Microsoft in the room, and the Microsoft rep goes "Wow, we should totally put that on TechNet."
This is one of those things.
If you want to remove the www prefix from a url for all SharePoint sites, here's how:
1. Download and install the URL Rewrite Module on all web front ends. Get it here: http://www.iis.net/downloads/microsoft/url-rewrite
2. Configure Alternate Access Mappings in SharePoint to allow the www url. We added an Internal URL for our WWW entry, and mapped it to the public url. Our AAM settings looked like this when we were done:

3. Add a binding in IIS for the additional WWW url. Our bindings looked like this:

4. Configure the URL Rewrite Module for the new address. Do that by:
- Adding a Blank Rule
- Enter the pattern http://www.somesite.com/*
- Choose Rewrite for the Action Type
- Enter the pattern http://somesite.com/*
- Save it.
Why this works:
SharePoint needs an Alternate Access Mapping for the www url. Once that's in place, IIS needs a binding to recognize the request from SharePoint. Once THAT is entered, the rewrite module will see the www request come in, pick it up, and reroute it.
The users will see the site automatically replace the URL to http://somesite.com.
This is one of those things.
If you want to remove the www prefix from a url for all SharePoint sites, here's how:
1. Download and install the URL Rewrite Module on all web front ends. Get it here: http://www.iis.net/downloads/microsoft/url-rewrite
2. Configure Alternate Access Mappings in SharePoint to allow the www url. We added an Internal URL for our WWW entry, and mapped it to the public url. Our AAM settings looked like this when we were done:
3. Add a binding in IIS for the additional WWW url. Our bindings looked like this:
4. Configure the URL Rewrite Module for the new address. Do that by:
- Adding a Blank Rule
- Enter the pattern http://www.somesite.com/*
- Choose Rewrite for the Action Type
- Enter the pattern http://somesite.com/*
- Save it.
Why this works:
SharePoint needs an Alternate Access Mapping for the www url. Once that's in place, IIS needs a binding to recognize the request from SharePoint. Once THAT is entered, the rewrite module will see the www request come in, pick it up, and reroute it.
The users will see the site automatically replace the URL to http://somesite.com.
Wednesday, March 16, 2016
Delete all users from a SharePoint group with Powershell
Add-PSSnapin Microsoft.SharePoint.Powershell
###########################
# "Enter the site URL here"
$SITEURL = "http://somesite.com"
# "Name of Site group from which users have to be removed"
$SITEGROUP = "Members"
###########################
$site = new-object Microsoft.SharePoint.SPSite ( $SITEURL )
$web = $site.OpenWeb()
"Web is : " + $web.Title
$oSiteGroup = $web.SiteGroups[$SITEGROUP];
"Site Group is :" + $oSiteGroup.Name
$oUsers = $oSiteGroup.Users
foreach ($oUser in $oUsers)
{
"Removing user : " + $oUser.Name
$oSiteGroup.RemoveUser($oUser)
}
###########################
# "Enter the site URL here"
$SITEURL = "http://somesite.com"
# "Name of Site group from which users have to be removed"
$SITEGROUP = "Members"
###########################
$site = new-object Microsoft.SharePoint.SPSite ( $SITEURL )
$web = $site.OpenWeb()
"Web is : " + $web.Title
$oSiteGroup = $web.SiteGroups[$SITEGROUP];
"Site Group is :" + $oSiteGroup.Name
$oUsers = $oSiteGroup.Users
foreach ($oUser in $oUsers)
{
"Removing user : " + $oUser.Name
$oSiteGroup.RemoveUser($oUser)
}
Sunday, February 28, 2016
Warm up SharePoint - Vickers Style
There are about a million of these scripts on the Internet, but this one is mine. Put it on a server, run it regularly in Task Scheduler, and forget about it.
The nice thing about this one is you don't have to change anything about it to run it on your farm. It will query SharePoint to get the relevant web applications, search centers, mysites, etc.
Add-PSSnapin Microsoft.SharePoint.PowerShell
try
{
# Set Variables
$MultiThreadSites = @()
$SingleThreadSites = @()
$WebServers = @()
$SearchServers = @()
$Servers = Get-SPServer | where {$_.Role -ne "Invalid"}
# Get Web Applications
$WebApps = Get-SPWebApplication
# Get Global Search Center Url
$SearchSvc = Get-SPEnterpriseSearchServiceApplication | Where {$_.Name -eq "Search Service Application"}
$SrcCenterUrl = $SearchSvc.SearchCenterUrl -Replace "/default.aspx", ""
# If search center is set
if($SrcCenterUrl)
{
# Set Various Search Urls
$SrcUrls = @("$($SrcCenterUrl)/default.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/results.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/peopleresults.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/conversationresults.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/results.aspx?k=test")
}
# Get Central Admin Url
$CentralAdmin = [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]::Local
$CentralAdminUrl = $CentralAdmin.Url
$HealthReportUrl = "$($CentralAdminUrl)/Lists/HealthReports"
$CAServer = $CentralAdmin.Url.split('//')[2].split('`:')[0]
# Loop through all the servers in farm
foreach($Server in $Servers)
{
# Create a variable of Server Name
$ServerName = $Server.Name
# Determine the farm Web Servers
If ($ServerName -notlike "SRPAPPPW003") {
$WebServiceIns = Get-SPServiceInstance -Server $ServerName | where {$_.TypeName -eq "Microsoft SharePoint Foundation Web Application"}
if($WebServiceIns.Status -eq "Online")
{
$WebServers += ,@($ServerName)
} }
# Determine the farm Search Servers
$SearchServiceIns = Get-SPServiceInstance -Server $ServerName | where {$_.TypeName -eq "SharePoint Server Search"}
if($SearchServiceIns.Status -eq "Online")
{
$SearchServers += ,@($ServerName)
}
}
# Loop through all the Web Applications
foreach($WebApp in $WebApps)
{
# Get the first site collection Url
$SiteCols = Get-SPSite -WebApplication $WebApp -Limit 5
# If there are Site Collections in this Web Application
if($SiteCols)
{
# Loop through all the Site Collections
foreach($SiteCol in $SiteCols)
{
$MultiThreadSites += $SiteCol.Url | Where {$_ -notlike "*$CAServer*"}
}
}
}
# Add Central Admin and Helath Check to the Site Array
#$SingleThreadSites += ,@($CentralAdminUrl)
#$SingleThreadSites += ,@($HealthReportUrl)
# Loop through all the Search Urls
foreach($SrcUrl in $SrcUrls)
{
# Add Url to the Site Array
$SingleThreadSites += ,@($SrcUrl)
}
# Loop through all Search Servers
foreach($SearchServer in $SearchServers)
{
# Add Url to the Site Array
$TopologyUrl = "http://$($SearchServer.ToLower()):32843/Topology/topology.svc"
$SingleThreadSites += ,@($TopologyUrl)
}
# Loop through all urls
foreach($Site in $SingleThreadSites)
{
Write-host "Loading $($Site)..." -NoNewline
$Url = "$($Site)"
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
# Loop through all site collections
foreach($Site in $MultiThreadSites)
{
# Loop through all web servers
foreach($WebServer in $WebServers)
{
Write-host "Loading $($Site) on server $($WebServer)..." -NoNewline
$Url = $($Site)
$BypassLocal = $false
$ProxyUri = "http://" + $WebServer
$Proxy = New-Object System.Net.WebProxy($ProxyUri, $BypassLocal)
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
$Request.Proxy = $Proxy
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$WebClient.Proxy = $Proxy
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
}
Write-host "Loading Central Admin on server $($CAServer)..." -NoNewline
$Url = $($CentralAdminUrl)
$BypassLocal = $false
$ProxyUri = $CentralAdminUrl
$Proxy = New-Object System.Net.WebProxy($ProxyUri, $BypassLocal)
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
$Request.Proxy = $Proxy
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$WebClient.Proxy = $Proxy
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
catch
{
Write-host "Error" -ForegroundColor Red
Write-host "Error at line $($_.InvocationInfo.ScriptLineNumber): $_" -ForegroundColor DarkGray
}
# Remove created variables
#Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
The nice thing about this one is you don't have to change anything about it to run it on your farm. It will query SharePoint to get the relevant web applications, search centers, mysites, etc.
Add-PSSnapin Microsoft.SharePoint.PowerShell
try
{
# Set Variables
$MultiThreadSites = @()
$SingleThreadSites = @()
$WebServers = @()
$SearchServers = @()
$Servers = Get-SPServer | where {$_.Role -ne "Invalid"}
# Get Web Applications
$WebApps = Get-SPWebApplication
# Get Global Search Center Url
$SearchSvc = Get-SPEnterpriseSearchServiceApplication | Where {$_.Name -eq "Search Service Application"}
$SrcCenterUrl = $SearchSvc.SearchCenterUrl -Replace "/default.aspx", ""
# If search center is set
if($SrcCenterUrl)
{
# Set Various Search Urls
$SrcUrls = @("$($SrcCenterUrl)/default.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/results.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/peopleresults.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/conversationresults.aspx")
$SrcUrls += ,@("$($SrcCenterUrl)/results.aspx?k=test")
}
# Get Central Admin Url
$CentralAdmin = [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]::Local
$CentralAdminUrl = $CentralAdmin.Url
$HealthReportUrl = "$($CentralAdminUrl)/Lists/HealthReports"
$CAServer = $CentralAdmin.Url.split('//')[2].split('`:')[0]
# Loop through all the servers in farm
foreach($Server in $Servers)
{
# Create a variable of Server Name
$ServerName = $Server.Name
# Determine the farm Web Servers
If ($ServerName -notlike "SRPAPPPW003") {
$WebServiceIns = Get-SPServiceInstance -Server $ServerName | where {$_.TypeName -eq "Microsoft SharePoint Foundation Web Application"}
if($WebServiceIns.Status -eq "Online")
{
$WebServers += ,@($ServerName)
} }
# Determine the farm Search Servers
$SearchServiceIns = Get-SPServiceInstance -Server $ServerName | where {$_.TypeName -eq "SharePoint Server Search"}
if($SearchServiceIns.Status -eq "Online")
{
$SearchServers += ,@($ServerName)
}
}
# Loop through all the Web Applications
foreach($WebApp in $WebApps)
{
# Get the first site collection Url
$SiteCols = Get-SPSite -WebApplication $WebApp -Limit 5
# If there are Site Collections in this Web Application
if($SiteCols)
{
# Loop through all the Site Collections
foreach($SiteCol in $SiteCols)
{
$MultiThreadSites += $SiteCol.Url | Where {$_ -notlike "*$CAServer*"}
}
}
}
# Add Central Admin and Helath Check to the Site Array
#$SingleThreadSites += ,@($CentralAdminUrl)
#$SingleThreadSites += ,@($HealthReportUrl)
# Loop through all the Search Urls
foreach($SrcUrl in $SrcUrls)
{
# Add Url to the Site Array
$SingleThreadSites += ,@($SrcUrl)
}
# Loop through all Search Servers
foreach($SearchServer in $SearchServers)
{
# Add Url to the Site Array
$TopologyUrl = "http://$($SearchServer.ToLower()):32843/Topology/topology.svc"
$SingleThreadSites += ,@($TopologyUrl)
}
# Loop through all urls
foreach($Site in $SingleThreadSites)
{
Write-host "Loading $($Site)..." -NoNewline
$Url = "$($Site)"
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
# Loop through all site collections
foreach($Site in $MultiThreadSites)
{
# Loop through all web servers
foreach($WebServer in $WebServers)
{
Write-host "Loading $($Site) on server $($WebServer)..." -NoNewline
$Url = $($Site)
$BypassLocal = $false
$ProxyUri = "http://" + $WebServer
$Proxy = New-Object System.Net.WebProxy($ProxyUri, $BypassLocal)
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
$Request.Proxy = $Proxy
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$WebClient.Proxy = $Proxy
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
}
Write-host "Loading Central Admin on server $($CAServer)..." -NoNewline
$Url = $($CentralAdminUrl)
$BypassLocal = $false
$ProxyUri = $CentralAdminUrl
$Proxy = New-Object System.Net.WebProxy($ProxyUri, $BypassLocal)
$Request = [System.Net.WebRequest]::Create($Url)
$Request.UseDefaultCredentials = $true
$Request.Proxy = $Proxy
try
{
$Response = $Request.GetResponse()
}
catch [System.Net.WebException]
{
$Response = $_.Exception.Response
}
$Status = [int]$Response.StatusCode
if($Status -eq 200)
{
$WebClient = New-Object Net.WebClient
$WebClient.UseDefaultCredentials = $true
$WebClient.Proxy = $Proxy
$PageContents = $WebClient.DownloadString($Url)
$WebClient.Dispose()
Write-host "200 OK" -ForegroundColor Green
}
else
{
Write-host "Error: $Status" -ForegroundColor Red
}
}
catch
{
Write-host "Error" -ForegroundColor Red
Write-host "Error at line $($_.InvocationInfo.ScriptLineNumber): $_" -ForegroundColor DarkGray
}
# Remove created variables
#Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
Thursday, February 25, 2016
Here's something you don't really want to see....ever
We ran into a unique error in Project Server 2013 a couple days ago. In short, what we found was if you are running a Bulk Update of all Project sites, there's a possibility of putting locks on your database if you are running an instance of Project Server that is highly customized.
The error we were seeing in the SharePoint logs was this: PWA:{PWA Url}, ServiceApp:Project Services Application, User:PROJECTSERVER\system, PSI: User {User Account} could not be authenticated because logon permission has not been granted.
In our case, the stored procedure for pub.MSP_AUTH_AuthenticateUserByAccount could not fire, not because of an access or authentication issue, but because a lock had been placed on the tempdb's log file.
In searching for the error, I saw something I've never seen before on Google.
Behold
You know you're having a bad day when even Google only has one idea.
The error we were seeing in the SharePoint logs was this: PWA:{PWA Url}, ServiceApp:Project Services Application, User:PROJECTSERVER\system, PSI: User {User Account} could not be authenticated because logon permission has not been granted.
In our case, the stored procedure for pub.MSP_AUTH_AuthenticateUserByAccount could not fire, not because of an access or authentication issue, but because a lock had been placed on the tempdb's log file.
In searching for the error, I saw something I've never seen before on Google.
Behold
You know you're having a bad day when even Google only has one idea.
Subscribe to:
Posts (Atom)
