Wednesday, March 9, 2016

Grant Full Control to Service Application in SharePoint

Adds a claims user to a Service Application with Full Control

function Add-User-To-Service-Application-Administrators([string] $account, [string] $serviceApplication)
{
    $principal = New-SPClaimsPrincipal $account -IdentityType WindowsSamAccountName
    $spapp = Get-SPServiceApplication -Name $serviceApplication
    $security = Get-SPServiceApplicationSecurity $spapp -Admin

    Grant-SPObjectSecurity $security $principal "Full Control"
    Set-SPServiceApplicationSecurity $spapp $security -Admin
    #(Get-SPServiceApplicationSecurity $spapp -Admin).AccessRules
}



Add-User-To-Service-Application-Administrators "DEV\SPAppPool" "User Profile Service Application"

Greatest PowerShell Ever Written - Show File Extensions!


I regularly log on to servers where I need to change explorer settings.  This function has saved me years.

It sets the explorer optiona to what I like.  Including showing file extensions.

function Set-Windows-File-Explorer-Folder-Options()
{
$key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
Set-ItemProperty $key Hidden 1
Set-ItemProperty $key HideFileExt 0
#This one can be dangerous Set-ItemProperty $key ShowSuperHidden 1

    Set-ItemProperty $key HideDrivesWithNoMedia 1
    Set-ItemProperty $key NavPaneExpandToCurrentFolder 1
    Set-ItemProperty $key NavPaneShowAllFolders 1
}

Set-Windows-File-Explorer-Folder-Options


Scheduled Task in PowerShell - ShutDown

Some servers need to shutdown to conserve power - its our only planet!


function Create-Shutdown-Scheduled-Task()
{
    #create a scheduled taks that will shutdown the VM after 5 mins, at 7pm
    $action = New-ScheduledTaskAction -Execute 'C:\Windows\System32\shutdown.exe'  -Argument ' /s /t 1 /f /c "shutting down for the day..."'

    $trigger =  New-ScheduledTaskTrigger -Daily -At 7pm
 
    Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Automated Shutdown" -Description "Business policy is to shutdown VMs at 7pm daily"  -User "$env:USERDOMAIN\$env:USERNAME" -Password 'DWProduct@1'

}

Create-Shutdown-Scheduled-Task

AppFabric Patch and update app.config in PowerShell

Updating the AppFabric is a pain.  Any mistakes and you will end up with a broken farm.  After wrecking a farm I decided to write a script.

This script installs CU7, and makes the recommended config file changes to take advantage of improved garbage collection.

In this example, we stop the Distributed Cache (this is critical!!!!), install App fabric CU7, update the app configs, repeat on all servers, wait a few minutes, start Distributed Cache on servers.

Sometimes it will take many minutes to stop the DC...

Import-Module Servermanager
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath


Add-PSSnapin Microsoft.sharepoint.powershell


function Patch-Configure-AppFabric-For-SharePoint()
{
    #VVVVVNB!!!
    Stop-SPDistributedCacheServiceInstance -Graceful

    #edit file for updated values
    $webConfig = "C:\Program Files\AppFabric 1.1 for Windows Server\DistributedCacheService.exe.config"
    $doc = (gc $webConfig) -as [xml]

    #might not have appsettings node
    $appSettingsnode = $doc.SelectSingleNode('configuration/appSettings')
    if($appSettingsnode -eq $null)
    {
       #$configurationnode = $doc.SelectSingleNode('configuration')
       $appSettingsnode = $doc.CreateElement('appSettings')
       $doc.configuration.AppendChild($appSettingsnode)
    }

    $newPropertyNode = $doc.SelectSingleNode('configuration/appSettings/add')
    if($newPropertyNode -eq $null)
    {
        $newPropertyNode = $doc.CreateNode("element", "add","")
        $newPropertyNode.SetAttribute("key", "backgroundGC")
        $newPropertyNode.SetAttribute("value", "true")

        $bypassPSShortcomings = $doc.SelectSingleNode('configuration/appSettings')
        $bypassPSShortcomings.AppendChild($newPropertyNode)

        $doc.Save($webConfig)  
    }

    #Install the CU
    $scriptpath = $MyInvocation.MyCommand.Path
    if($scriptpath -eq $null) #if running fomr ISE
    {
       $dir = "\\your-server-here\c$\Package\"
    }
    else
    {
        $dir = Split-Path $scriptpath
    }

    $AppFabric = "$dir\AppFabric-KB3092423-x64-ENU.exe"

    $setup=Start-Process $AppFabric -ArgumentList "/S" -Wait

    Start-Sleep 120  #just in case...
 

}

Patch-Configure-AppFabric-For-SharePoint




Run this after repeating above ps1 on the servers

Do not run this till its all finished.  I also leave it to you to determine where Distributed Cache is intended to be running.
    $instance = Get-SPServiceInstance | ? {$_.TypeName -eq "Distributed Cache" -and $_.Server.Name -eq $env:computername}
    $instance.Provision()



SQL Server - Enable Server Protocols Powershell

There are some settings that I do regularly so I automated them

After SQL server is installed (and depending on your need), it needs the protocols enabled.  I enable TCP and Named Pipes.

Import-Module Servermanager

function ChangeSQLProtocolStatus($server,$instance,$protocol,$enable){

    $smo = 'Microsoft.SqlServer.Management.Smo.'
   
    $wmi = new-object ($smo + 'Wmi.ManagedComputer')

    $singleWmi = $wmi | where {$_.Name -eq $server}  

    $uri = "ManagedComputer[@Name='$server']/ServerInstance[@Name='$instance']/ServerProtocol[@Name='$protocol']"
   
    $protocol = $singleWmi.GetSmoObject($uri)
   
    $protocol.IsEnabled = $enable
   
    $protocol.Alter()
   
    $protocol
}

[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement")

#or else sharepoint won't install
ChangeSQLProtocolStatus -server $env:COMPUTERNAME -instance "SP2013" -protocol "TCP" -enable $true
#or else sharepoint won't install
ChangeSQLProtocolStatus -server $env:COMPUTERNAME -instance "SP2013" -protocol "NP" -enable $true




Tuesday, February 16, 2016

SharePoint 2013 Performance Optimization in PowerShell

SharePoint 2013 Performance Optimizations in PowerShell

Developer machines in particular need to make maximum utilization of RAM.

SetSQLInstanceMemory, sets the RAM of the SQL server.  Operating System gets 10% and at least 2GB.  SQL Server, for SharePoint, gets between 2GB and 4GB on a developer machine (its got to share RAM with Visual Studio and SharePoint).

SetSQLInstanceMemory ".\SP2013" 3072 2048

SetNodeRunnerMemoryLimit, is not supported, as the Search uses most of the memory, you can  reduce it here.  It needs at least a 1 GB, or it keeps crashing.

SetObjectCachingOnSite, can be run to make SharePoint a bit faster.  I do it on most farms.

Set-SPEnterpriseSearchService -PerformanceLevel Reduced, I only run this in developer machines, or if there is no need for full power search.

New-SPEnterpriseSearchSiteHitRule -Name $env:COMPUTERNAME -Behavior 'SimultaneousRequests' -HitRate 2,  This one I use on production and developer farms.  The search will absolutely smash your servers unless you set this in farms whithout dedicated search servers.

Set-SPLogLevel -TraceSeverity Medium -EventSeverity Information.  If the farm is stable consider setting this.  The more the information that SharePoint logs the slower your farm will be.

Set-SPDiagnosticConfig -LogMaxDiskSpaceUsageEnabled
Set-SPDiagnosticConfig -LogDiskSpaceUsageGB 1
Set-SPDiagnosticConfig -EventLogFloodProtectionEnabled
I always set these, options vary.

Get-SPUsageDefinition | ForEach-Object { if ($_.Enabled -eq "False") { Set-SPUsageDefinition -Identity $_.Name -DaysRetained 1 }}.  On a dev machine DaysRetained = 1, On production you may need several weeks.



Add-PSSnapin Microsoft.sharepoint.powershell
function SetSQLInstanceMemory ([string]$SQLInstanceName = ".", [int]$maxMem = $null, [int]$minMem = $null)
{
    [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
    $srv = new-object Microsoft.SQLServer.Management.Smo.Server($SQLInstanceName)
    $srv.ConnectionContext.LoginSecure = $true
    $srv.Configuration.MaxServerMemory.ConfigValue = $maxMem
    $srv.Configuration.MinServerMemory.ConfigValue = $minMem
    $srv.Configuration.Alter()
}
function SetNodeRunnerMemoryLimit()
{
    write-host -ForegroundColor Red "Setting NodeRunner memory, not supported in Production or UAT"
    #edit file for updated values
    $webConfig = "C:\Program Files\Microsoft Office Servers\15.0\Search\Runtime\1.0\noderunner.exe.config"
    $doc = (gc $webConfig) -as [xml]
    $nodeRunnerSettingsnode = $doc.SelectSingleNode('configuration/nodeRunnerSettings')
    #not support!!!!!
    #for dev only
    $nodeRunnerSettingsnode.Attributes['memoryLimitMegabytes'].Value = "1024"
    $doc.Save($webConfig)
    Restart-Service SPSearchHostController
    write-host -ForegroundColor Red "Setting NodeRunner memory, not supported in Production or UAT"
}

function GetObjectCachingOnSite([string] $siteUrl)
{
    [System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint.Publishing”)
    $cacheSettings = new-object Microsoft.SharePoint.Publishing.SiteCacheSettingsWriter($siteUrl);
    $cacheSettings.EnableCache = $true;
    $cacheSettings.Update();
}

#set memory used by SQL
SetSQLInstanceMemory ".\SP2013" 3072 2048
#reduce crawl
Set-SPEnterpriseSearchService -PerformanceLevel Reduced
#set crawler impact rule
New-SPEnterpriseSearchSiteHitRule -Name $env:COMPUTERNAME -Behavior 'SimultaneousRequests' -HitRate 2
#set noderunner memory
SetNodeRunnerMemoryLimit
#set minumum
Set-SPLogLevel -TraceSeverity Medium -EventSeverity Information
#general settings
Set-SPDiagnosticConfig -LogMaxDiskSpaceUsageEnabled
Set-SPDiagnosticConfig -LogDiskSpaceUsageGB 1
Set-SPDiagnosticConfig -EventLogFloodProtectionEnabled
#stop logs from growing
Get-SPUsageDefinition | ForEach-Object { if ($_.Enabled -eq "False") { Set-SPUsageDefinition -Identity $_.Name -
DaysRetained 1 }}
SetObjectCachingOnSite "https://test.com"