Provision-AutoGenKeys.ps1 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. param (
  2. [Parameter(Mandatory = $True)]
  3. [string] $appPoolName
  4. )
  5. # Provisions the HKLM registry so that the specified user account can persist auto-generated machine keys.
  6. function Provision-AutoGenKeys {
  7. [CmdletBinding()]
  8. param (
  9. [ValidateSet("2.0", "4.0")]
  10. [Parameter(Mandatory = $True)]
  11. [string] $frameworkVersion,
  12. [ValidateSet("32", "64")]
  13. [Parameter(Mandatory = $True)]
  14. [string] $architecture,
  15. [Parameter(Mandatory = $True)]
  16. [string] $sid
  17. )
  18. process {
  19. # We require administrative permissions to continue.
  20. if (-Not (new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
  21. Write-Error "This cmdlet requires Administrator permissions."
  22. return
  23. }
  24. # Open HKLM with an appropriate view into the registry
  25. if ($architecture -eq "32") {
  26. $regView = [Microsoft.Win32.RegistryView]::Registry32;
  27. } else {
  28. $regView = [Microsoft.Win32.RegistryView]::Registry64;
  29. }
  30. $baseRegKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $regView)
  31. # Open ASP.NET base key
  32. if ($frameworkVersion -eq "2.0") {
  33. $expandedVersion = "2.0.50727.0"
  34. } else {
  35. $expandedVersion = "4.0.30319.0"
  36. }
  37. $softwareMicrosoftKey = $baseRegKey.OpenSubKey("SOFTWARE\Microsoft\", $True);
  38. $aspNetKey = $softwareMicrosoftKey.OpenSubKey("ASP.NET", $True);
  39. if ($aspNetKey -eq $null)
  40. {
  41. $aspNetKey = $softwareMicrosoftKey.CreateSubKey("ASP.NET")
  42. }
  43. $aspNetBaseKey = $aspNetKey.OpenSubKey("$expandedVersion", $True);
  44. if ($aspNetBaseKey -eq $null)
  45. {
  46. $aspNetBaseKey = $aspNetKey.CreateSubKey("$expandedVersion")
  47. }
  48. # Create AutoGenKeys subkey if it doesn't already exist
  49. $autoGenBaseKey = $aspNetBaseKey.OpenSubKey("AutoGenKeys", $True)
  50. if ($autoGenBaseKey -eq $null) {
  51. $autoGenBaseKey = $aspNetBaseKey.CreateSubKey("AutoGenKeys")
  52. }
  53. # SYSTEM, ADMINISTRATORS, and the target SID get full access
  54. $regSec = New-Object System.Security.AccessControl.RegistrySecurity
  55. $regSec.SetSecurityDescriptorSddlForm("D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GA;;;$sid)")
  56. $userAutoGenKey = $autoGenBaseKey.OpenSubKey($sid, $True)
  57. if ($userAutoGenKey -eq $null) {
  58. # Subkey didn't exist; create and ACL appropriately
  59. $userAutoGenKey = $autoGenBaseKey.CreateSubKey($sid, [Microsoft.Win32.RegistryKeyPermissionCheck]::Default, $regSec)
  60. } else {
  61. # Subkey existed; make sure ACLs are correct
  62. $userAutoGenKey.SetAccessControl($regSec)
  63. }
  64. }
  65. }
  66. $ErrorActionPreference = "Stop"
  67. if (Get-Command Get-IISAppPool -errorAction SilentlyContinue)
  68. {
  69. $processModel = (Get-IISAppPool $appPoolName).processModel
  70. }
  71. else
  72. {
  73. Import-Module WebAdministration
  74. $processModel = Get-ItemProperty -Path "IIS:\AppPools\$appPoolName" -Name "processModel"
  75. }
  76. $identityType = $processModel.identityType
  77. Write-Output "Pool process model: '$identityType'"
  78. Switch ($identityType)
  79. {
  80. "LocalService" {
  81. $userName = "LocalService";
  82. }
  83. "LocalSystem" {
  84. $userName = "System";
  85. }
  86. "NetworkService" {
  87. $userName = "NetworkService";
  88. }
  89. "ApplicationPoolIdentity" {
  90. $userName = "IIS APPPOOL\$appPoolName";
  91. }
  92. "SpecificUser" {
  93. $userName = $processModel.userName;
  94. }
  95. }
  96. Write-Output "Pool user name: '$userName'"
  97. Try
  98. {
  99. $poolSid = (New-Object System.Security.Principal.NTAccount($userName)).Translate([System.Security.Principal.SecurityIdentifier]).Value
  100. }
  101. Catch [System.Security.Principal.IdentityNotMappedException]
  102. {
  103. Write-Error "Application pool '$appPoolName' account cannot be resolved."
  104. }
  105. Write-Output "Pool SID: '$poolSid'"
  106. Provision-AutoGenKeys "4.0" "32" $poolSid
  107. Provision-AutoGenKeys "4.0" "64" $poolSid