Working with Request Manager in SharePoint 2013

I haven't seen a lot of information out and about on this yet, so I thought I'd take a little time to frankly - get into some PowerShell - for Request Manager (RM). For those of you who aren't familiar with RM, it's a new piece of SharePoint 2013 designed to do SharePoint request routing and throttling. By having knowledge over the nature of incoming requests – for example, the user agent, requested URL, or source IP – SharePoint can customize the response to each request. It can route it based on rules you define, or it can throttle the request completely. RM rules are applied per web app, just like throttling is done in SharePoint 2010. 

At a high level, the goals of RM are this:

  • RM can route to WFEs with better health, keeping low-health WFEs alive
  • RM can identify harmful requests and deny them immediately
  • RM can prioritize requests by throttling lower-priority ones (bots) to serve higher-priority ones (end-users)
  • RM can send all requests of specific type, like search for example, to specific machines
  • Isolated traffic can help troubleshoot errors on one machine
  • RM can send heavy requests to more powerful WFEs

Routing and throttling rules are implemented like this:

  • Routing rules route requests and are associated with MachinePools
  • MachinePools contain servers
  • Servers use weights for routing – static weights and health weights
  • Static weights are constant for WFEs; health weights change dynamically based on health scores

Okay, so that's the basic overview of what they are - there should be other documentation on TechNet if you want more details on the features and use for RM. If you're reading this, I'm assuming you know enough about it (or are curious enough about it) that you want to actually do some work with it. So I'm just going to throw down some PowerShell here to help get you started. These are cmdlets that I've found useful when working with RM. The basic process you go through is something like this:

  • Get a reference to the SPWebApplication
  • Get a reference to the request management settings for the web application
  • Create one or more criteria
  • A request must match ALL criteria for a rule in order to match the rule (i.e. they are AND’d together)
  • Get a reference to a machine pool, or create a new one if needed
  • Add the rule

Let's walk through an example now:

#Get a reference to the SPWebApplication
$w = Get-SPWebApplication -identity https://foo

#Get a reference to the request management settings for the web application
$rmset = $w | Get-SPRequestManagementSettings

#Create one or more criteria
$criteria = New-SPRequestManagementRuleCriteria -Property Url -Value ".*\.docx" -MatchType Regex

#Get a reference to a machine pool, or create a new one if needed
$mp = Add-SPRoutingMachinePool -RequestManagementSettings $rmset -Name MyRulePool -MachineTargets ($rmset | Get-SPRoutingMachineInfo -Name WFE1)

#Add the rule
$rmset | Add-SPRoutingRule -Name "Word Doc Rule" -Criteria $criteria -MachinePool $mp

Let's look at that routing rule now:
$rr = $rmset | Get-SPRoutingRule -Name "Word Doc Rule"

#see the criteria

#change the expiration date and time of the routing rule
$rr.Expiration = "12/25/2013 5:00:00 PM"

There you go - now you have a routing rule. Creating a throttling rule is very similar:

#Add a new criteria rule that looks for OneNote requests. It can do this by examining the UserAgent in the request and looking for the header that OneNote uses.
$criteria = New-SPRequestManagementRuleCriteria -Property UserAgent -Value ".*Microsoft Office OneNote 2010*" -MatchType Regex

#Add a throttling rule that uses the criteria rule when the server health reaches a score of 8.
#Note that throttle rules apply to the entire web application, #not to individual machines so you don’t
#use a machine pool with it.
$rmset | Add-SPThrottlingRule -Name "OneNote Throttle Rule" -Criteria $criteria -Threshold 8

#now view all routing rules for the web application

#View all of the throttling rules


Let's look a little deeper at working with Machine Pools now:

#Get all routing machines that are available
Get-SPWebApplication | Get-SPRequestManagementSettings | Get-SPRoutingMachineInfo -Availability Available

#Get every machine in a specific pool
Get-SPWebApplication | Get-SPRequestManagementSettings | Get-SPRoutingMachinePool -Name yourPoolName | % { $_.MachineTargets} | Format-Table

#Add machine WFE1 to every machine pool for a particular web application; a million thanks to Tyler who helped me with this one - I ain't a PowerShell guy really
$a = Get-SPWebApplication -Identity https://contoso
$b = $a | Get-SPRequestManagementSettings | Get-SPRoutingMachineInfo -Name WFE1
Get-SPWebApplication | Get-SPRequestManagementSettings | Get-SPRoutingMachinePool | % { $_ | Set-SPRoutingMachinePool -machinetargets ($_.machinetargets + $b) }

#Add machine WFE1 to a specific pool
$a = Get-SPWebApplication -Identity https://contoso
$b = $a | Get-SPRequestManagementSettings | Get-SPRoutingMachineInfo -Name WFE1
$pool = $a | Get-SPRequestManagementSettings | Get-SPRoutingMachinePool -Name yourPoolName
$pool | Set-SPRoutingMachinePool -MachineTargets ($pool.MachineTargets + $b)

#Remove WFE1 from every machine pool
Get-SPWebApplication | Get-SPRequestManagementSettings | Get-SPRoutingMachineInfo -Name WFE1 | Remove-SPRoutingMachineInfo

Okay, there you have it folks. That should give you plenty to start working with.