PSIISHelper.psm1
#Region IsLocal <# .SYNOPSIS Test to see if the provided computer name is the local computer. .DESCRIPTION This function tests to see if the provided computer name is the local computer. .PARAMETER ComputerName The computer name to test. .EXAMPLE IsLocal "MyComputer" Description ----------- This function tests to see if the provided computer name is the local computer. .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function IsLocal() { [CmdletBinding()] [OutputType([bool])] Param( [System.String]$ComputerName ) Begin { $LocalValues = @( 'localhost', '.', $env:COMPUTERNAME ) } Process { Try { $IsLocal = $LocalValues | Foreach-Object { if ($_ -eq $ComputerName) { Write-Output $true break } } [bool]$IsLocal } Catch { Throw $_ } } End {} } #EndRegion IsLocal #Region Get-PSIISBinding <# .SYNOPSIS Returns information about IIS web site bindings .DESCRIPTION Takes a list of IIS servers and returns all the web site bindings Requires administrator permissions. .PARAMETER ComputerName A string or string array of server names. .PARAMETER Port The port number to use for the connection. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE Get-WebSiteBinding MY_SERVER_NAME Description ----------- Returns all the web site bindings for the specified server. .EXAMPLE Get-WebSiteBinding MY_SERVER_NAME1, MY_SERVER_NAME2 Description ----------- Returns all the web site bindings for the specified servers. .EXAMPLE "MY_SERVER_NAME" | Get-WebSiteBinding Description ----------- Returns all the web site bindings for the specified server. .EXAMPLE @("MY_SERVER_NAME1", "MY_SERVER_NAME2") | Get-WebSiteBinding Description ----------- Returns all the web site bindings for the specified servers. .EXAMPLE Get-Content myServerNames.txt | Get-WebSiteBinding .EXAMPLE Get-WebSiteBinding -ComputerName "MY_SERVER_NAME" -Port 1234 -Credential $PSCredential Description ----------- Returns all the web site bindings for the specified server, using the specified credential. .NOTES Author: Matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> function Get-PSIISBinding() { [CmdletBinding()] Param ( [Parameter( ValueFromPipeline )] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter()] [System.String] $Port = '*', [PSCredential]$Credential = $script:PSIISCredential ) Begin { Write-Verbose -Message "Starting Get-PSIISBinding" $scriptBlock = { [CmdletBinding()] Param( [System.String] $Port ) Import-Module WebAdministration; $sites = Get-ChildItem -path IIS:\Sites foreach ($Site in $sites) { foreach ($Bind in (Get-WebBinding $Site.Name)) { foreach ($bindinfo in ($Bind | Select-Object -ExpandProperty bindingInformation)) { $bindingInformation = @($bindinfo -split ':') if ('*' -ne $Port) { If ($Port -ne $bindingInformation[1]) { continue } } [pscustomobject]@{ Server = $env:COMPUTERNAME Sitename = $Site.name Id = $Site.id State = $Site.State PhysicalPath = $Site.physicalPath ApplicationPool = $Site.applicationPool Protocol = $Bind.Protocol SslFlags = $Bind.sslFlags IpAddress = $bindingInformation[0] Port = $bindingInformation[1] HostName = $bindingInformation[2] } } } } } } Process { Switch($Port) { 'HTTP' {$Port = '80'} 'HTTPS' {$Port = '443'} DEFAULT {} } $ComputerName | Foreach-Object { Write-Verbose "Retrieving IIS information from $_" If (IsLocal $_) { Write-Verbose "$($MyInvocation.MyCommand.Name): Running on local computer: $env:COMPUTERNAME" & $scriptBlock -Port $Port -Verbose:$VerbosePreference | Select-Object -ExcludeProperty PSComputerName, RunspaceID, PSShowComputerName } Else { Write-Verbose "$($MyInvocation.MyCommand.Name): Running on remote computer: $_" $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Port) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID, PSShowComputerName } } } } #EndRegion Get-PSIISBinding #Region Get-PSIISPool <# .SYNOPSIS Get application pool information. .DESCRIPTION Query one or multiple remote servers for their application pools and other information. .PARAMETER ComputerName Specify a remote computer to run against. .PARAMETER Name Specify the name of the Application Pool to search for. .PARAMETER State Specify the state of the application pool to query. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE PS> Get-PSIISPool -ComputerName some-remote-pc1 Description ----------- Query 'some-remote-pc1' for all started app pools. .EXAMPLE PS> Get-PSIISPool -ComputerName WebServer01 -Name SiteAppPool_01 Description ----------- This will get the single app pool SiteAppPool_01 from WebServer01 .EXAMPLE PS> Get-PSIISPool -ComputerName WebServer01 -State Stopped Description ----------- Get all stopped app pools from WebServer01 .EXAMPLE PS> Get-PSIISPool WebServer01,WebServer02 -State * Description ----------- Search for all app pools (all states) from WebServer01 and WebServer02 .OUTPUTS [PSCustomObject]@{ Name # Name of Application Pool State # State of Application Pool Applications # Site Names that are in this Application Pool PSComputerName # ComputerName that the Application Pool lives on. } .NOTES Author: Matthew.DeGarmo Github: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Get-PSIISPool() { [CmdletBinding()] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server', 'PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('ApplicationPool')] [System.String] $Name, [Parameter()] [ValidateSet('Started','Stopped', '*')] [System.String] $State = '*', [PSCredential]$Credential = $script:PSIISCredential ) Begin { $OriginalFormatEnumerationLimit = $FormatEnumerationLimit $global:FormatEnumerationLimit = -1 } Process { if ($_ -is [System.Object]) { $Pool = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName) # Name = ($_.ApplicationPool) ? $_.ApplicationPool : $_.Name } If ($_.Server) { $Pool['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Pool['ComputerName'] = $_.ComputerName } Else { $Pool['ComputerName'] = $_.PSComputerName } } If ($_.ApplicationPool) { $Pool['Name'] = $_.ApplicationPool } Else { $Pool['Name'] = $_.Name } } else { $Pool = @{ ComputerName = $ComputerName Name = $Name } } $ScriptBlock = { Param( $InputObject, [System.String]$State ) Write-Verbose "$($COMPUTERNAME)`: Retrieving pool information..." Import-Module WebAdministration $Pools = Get-ChildItem 'IIS:\AppPools' | Where-Object { ($_.State -like $State) -and ($_.Name -match $InputObject.Name) } $Sites = Get-ChildItem 'IIS:\Sites' $Pools | Foreach-Object { $Pool = $_ [PSCustomObject] @{ Name = $Pool.Name State = $Pool.State Applications = ($Sites | Where-Object {$_.applicationPool -eq $Pool.Name}).Name ComputerName = $env:COMPUTERNAME } } } $Pool.ComputerName | Foreach-Object { If (IsLocal $_) { & $ScriptBlock -InputObject $Pool -State $State } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($_, $State) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } End { $global:FormatEnumerationLimit = $OriginalFormatEnumerationLimit } } #EndRegion Get-PSIISPool #Region Get-PSIISSite <# .SYNOPSIS Get IIS Site information. .DESCRIPTION Get IIS Site information. .PARAMETER ComputerName Specify a remote computer to run against. .PARAMETER Name Specify the name of the Application Pool to search for. .PARAMETER State Specify the state of the application pool to query. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE Get-PSIISSite -ComputerName "localhost" -Name "DefaultSite" .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo #> Function Get-PSIISSite() { [CmdletBinding()] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server', 'PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Site')] [System.String] $Name, [Parameter()] [ValidateSet('Started','Stopped', '*')] [System.String] $State = '*', [PSCredential]$Credential = $script:PSIISCredential ) Begin { $OriginalFormatEnumerationLimit = $FormatEnumerationLimit $global:FormatEnumerationLimit = -1 } Process { $ScriptBlock = { Param( [System.String]$Name, [System.String]$State ) Write-Verbose "$($COMPUTERNAME)`: Retrieving Site information..." Import-Module WebAdministration $WhereList = New-Object System.Collections.ArrayList $Where = $null If ($Name) {[void]$WhereList.Add('$_.Name -like $Name')} If ($State) {[void]$WhereList.Add('$_.State -like $State')} $Where = [scriptblock]::Create($WhereList -join " -and ") Get-ChildItem 'IIS:\Sites' | Where-Object $Where | Foreach-Object { [PSCustomObject] @{ Name = $_.Name State = $_.State ApplicationPool = $_.ApplicationPool ComputerName = $env:COMPUTERNAME } } } $ComputerName | Foreach-Object { If (IsLocal $_) { & $ScriptBlock -Name $Name -State $State } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Name, $State) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } End { $global:FormatEnumerationLimit = $OriginalFormatEnumerationLimit } } #EndRegion Get-PSIISSite #Region New-PSIISSession <# .SYNOPSIS Create a new PSCredential to be used for the current session. .DESCRIPTION This will store an environment credential for the current session for PSIISHelper commands. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object. .PARAMETER PassThru If true, the credential will be passed through to the pipeline. .EXAMPLE New-PSIISSession Description ----------- Creates a new PSCredential object to be used for the current session. .EXAMPLE New-PSIISSession -Credential $cred -PassThru Description ----------- Passes a user-provided credential and creates a new PSCredential object to be used for the current session. The credential will be passed through to the pipeline using -PassThru. .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function New-PSIISSession() { [CmdletBinding()] Param( [PSCredential]$Credential = (Get-Credential), [switch]$PassThru ) Begin {} Process { Try { $script:PSIISCredential = $Credential If ($PassThru) { Write-Output $script:PSIISCredential } } Catch { Throw $_ } } End {} } #EndRegion New-PSIISSession #Region Remove-PSIISSession <# .SYNOPSIS This function is used to remove the session credential for PSIISHelper. .DESCRIPTION This function is used to remove stored session credential that the PSIISHelper commands use. .EXAMPLE Remove-PSIISSession Description ----------- This function removes the stored session credential that the PSIISHelper commands use. .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Remove-PSIISSession() { [CmdletBinding()] Param() Begin {} Process { Try { Get-Variable PSIISCredential -ErrorAction SilentlyContinue | Remove-Variable } Catch { Throw $_ } } End {} } #EndRegion Remove-PSIISSession #Region Restart-PSIISPool <# .SYNOPSIS Restart an application pool. .DESCRIPTION Supply the web server and application pool to recycle. .PARAMETER ComputerName Specify the remote server to run against. .PARAMETER Name Specify the pool name to recycle. .PARAMETER Sites Specify the site names that are tied to this pool. This parameter is meant to support Pipeline values, but is not required to specify manually. Example: $Pool | Restart-PSIISPool # $Pool will have Sites information and pass it through the pipeline. Restart-PSIISPool -ComputerName Server1 -Name Pool1 # No site information will be included.. .PARAMETER PassThru If true, the command will return the IIS information. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE PS> Restart-PSIISPool -ComputerName WebServer01 -Name DefaultSitePool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01 -Name DefaultSitePool | Restart-PSIISPool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01,WebServer02 | Restart-PSIISPool Description ----------- CAUTION: This will recycle ALL app pools on WebServer01 and WebServer02. .EXAMPLE PS> Get-WebsiteInformation url.matthewjdegarmo.com | Restart-PSIISPool Description ----------- If url.matthewjdegarmo.com is found, this will prompt to recycle the app pool it is using. You should only do this if you KNOW that this is the only site on the found Application Pool. .NOTES Author: Matthew.DeGarmo Handle: @matthewjdegarmo #> Function Restart-PSIISPool() { [CmdletBinding( SupportsShouldProcess, ConfirmImpact = "High" )] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server', 'PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('ApplicationPool')] [System.String] $Name, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Sitename', 'Applications')] [System.String[]] $Sites, [switch]$PassThru, [PSCredential]$Credential = $script:PSIISCredential ) Begin {} Process { #Region Dynamic Pipeline handling if ($_ -is [System.Object]) { $Pool = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName).ToUpper() # Name = ($_.ApplicationPool) ? $_.ApplicationPool : $_.Name # Sites = ($_.SiteName) ? $_.SiteName : (($_.Applications) ? $_.Applications : $_.Sites) } If ($_.Server) { $Pool['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Pool['ComputerName'] = $_.ComputerName } Else { $Pool['ComputerName'] = $_.PSComputerName } } If ($_.ApplicationPool) { $Pool['Name'] = $_.ApplicationPool } Else { $Pool['Name'] = $_.Name } If ($_.SiteName) { $Pool['Sites'] = $_.SiteName } Else { If ($_.Applications) { $Pool['Sites'] = $_.Applications } Else { $Pool['Sites'] = $_.Sites } } } else { $Pool = @{ ComputerName = $ComputerName.ToUpper() Name = $Name } If ($Sites) { $Pool['Sites'] = $Sites.ToUpper() } else { $Pool['Sites'] = (Get-PSIISPool -ComputerName $Pool.ComputerName -Name $Pool.Name).Applications } } #EndRegion Dynamic Pipeline handling if ($PSCmdlet.ShouldProcess($Pool.ComputerName, "Recycle $($Pool.Name) pool containing sites: $($Pool.Sites)")) { $ScriptBlock = { [CmdletBinding()] Param( $Pool, [switch]$PassThru ) Write-Verbose "$($Pool.ComputerName): Recycling Pool: $($Pool.Name)" Import-Module WebAdministration Try { Restart-WebAppPool -Name $Pool.Name } Catch { $_ } If ($PassThru) { Get-PSIISPool -Name $Pool.Name -State 'Started' } } If (IsLocal $Pool.ComputerName) { & $ScriptBlock -Pool $Pool -PassThru:$PassThru } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Pool, $PassThru) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } } #EndRegion Restart-PSIISPool #Region Restart-PSIISSite <# .SYNOPSIS Restart a Website. .DESCRIPTION Supply the web server and website to restart. .PARAMETER ComputerName Specify the remote server to run against. .PARAMETER Name Specify the website name to restart. .PARAMETER PassThru If true, the command will return the IIS information. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE PS> Restart-PSIISSite -ComputerName WebServer01 -Name DefaultSite Description ----------- This will restart the website DefaultSite on WebServer01 .NOTES Author: Matthew.DeGarmo Github: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Restart-PSIISSite() { [CmdletBinding( SupportsShouldProcess, ConfirmImpact="High" )] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server','PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Sitename')] [System.String] $Name, [switch]$PassThru, [PSCredential]$Credential = $script:PSIISCredential ) Begin {} Process { if ($_ -is [System.Object]) { $Site = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName) # Name = ($_.Sitename) ? $_.Sitename : $_.Name } If ($_.Server) { $Site['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Site['ComputerName'] = $_.ComputerName } Else { $Site['ComputerName'] = $_.PSComputerName } } If ($_.Sitename) { $Site['Name'] = $_.Sitename } Else { $Site['Name'] = $_.Name } } else { $Site = @{ ComputerName = $ComputerName Name = $Name } } if ($PSCmdlet.ShouldProcess($Site.ComputerName, "Restart site: $($Site.Name)")) { $ScriptBlock = { [CmdletBinding()] Param( $Site, [switch]$PassThru ) Import-Module WebAdministration Stop-Website -Name $Site.Name -ErrorAction SilentlyContinue Start-Website -Name $Site.Name -ErrorAction SilentlyContinue -PassThru:$PassThru } $Site.ComputerName | FOreach-Object { If (IsLocal $_) { & $ScriptBlock -Site $Site -PassThru:$PassThru } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Site, $PassThru) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } } } #EndRegion Restart-PSIISSite #Region Start-PSIISPool <# .SYNOPSIS Restart an application pool. .DESCRIPTION Supply the web server and application pool to recycle. .PARAMETER ComputerName Specify the remote server to run against. .PARAMETER Name Specify the pool name to recycle. .PARAMETER Sites Specify the site names that are tied to this pool. This parameter is meant to support Pipeline values, but is not required to specify manually. Example: $Pool | Restart-PSIISPool # $Pool will have Sites information and pass it through the pipeline. Restart-PSIISPool -ComputerName Server1 -Name Pool1 # No site information will be included.. .PARAMETER PassThru If true, the command will return the IIS information. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE PS> Restart-PSIISPool -ComputerName WebServer01 -Name DefaultSitePool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01 -Name DefaultSitePool | Restart-PSIISPool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01,WebServer02 | Restart-PSIISPool Description ----------- CAUTION: This will recycle ALL app pools on WebServer01 and WebServer02. .EXAMPLE PS> Get-WebsiteInformation url.matthewjdegarmo.com | Restart-PSIISPool Description ----------- If url.matthewjdegarmo.com is found, this will prompt to recycle the app pool it is using. You should only do this if you KNOW that this is the only site on the found Application Pool. .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Start-PSIISPool() { [CmdletBinding( SupportsShouldProcess, ConfirmImpact = "High" )] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server', 'PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('ApplicationPool')] [System.String] $Name, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Sitename', 'Applications')] [System.String[]] $Sites, [switch]$PassThru, [PSCredential]$Credential = $script:PSIISCredential ) Begin {} Process { #Region Dynamic Pipeline handling if ($_ -is [System.Object]) { $Pool = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName).ToUpper() # Name = ($_.ApplicationPool) ? $_.ApplicationPool : $_.Name # Sites = ($_.SiteName) ? $_.SiteName : (($_.Applications) ? $_.Applications : $_.Sites) } If ($_.Server) { $Pool['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Pool['ComputerName'] = $_.ComputerName } Else { $Pool['ComputerName'] = $_.PSComputerName } } If ($_.ApplicationPool) { $Pool['Name'] = $_.ApplicationPool } Else { $Pool['Name'] = $_.Name } If ($_.SiteName) { $Pool['Sites'] = $_.SiteName } Else { If ($_.Applications) { $Pool['Sites'] = $_.Applications } Else { $Pool['Sites'] = $_.Sites } } } else { $Pool = @{ ComputerName = $ComputerName.ToUpper() Name = $Name } If ($Sites) { $Pool['Sites'] = $Sites.ToUpper() } else { $Pool['Sites'] = (Get-PSIISPool -ComputerName $Pool.ComputerName -Name $Pool.Name).Applications } } #EndRegion Dynamic Pipeline handling if ($PSCmdlet.ShouldProcess($Pool.ComputerName, "Start $($Pool.Name) pool containing sites: $($Pool.Sites)")) { $ScriptBlock = { [CmdletBinding()] Param( $Pool, [switch]$PassThru ) Write-Verbose "$($Pool.ComputerName): Starting Pool: $($Pool.Name)" Import-Module WebAdministration Start-WebAppPool -Name $Pool.Name -ErrorAction SilentlyContinue -PassThru:$PassThru } If (IsLocal $Pool.ComputerName) { & $ScriptBlock -Pool $Pool -PassThru:$PassThru } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Pool, $PassThru) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } } #EndRegion Start-PSIISPool #Region Start-PSIISSite <# .SYNOPSIS Start an IIS Site. .DESCRIPTION Start an IIS Site. .PARAMETER ComputerName Specify a remote computer to run against. .PARAMETER Name Specify the name of the IIS Site to search for. .PARAMETER PassThru If true, the command will return the IIS information. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE Start-PSIISSite -ComputerName localhost -Name MySite .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Start-PSIISSite() { [CmdletBinding( SupportsShouldProcess, ConfirmImpact="High" )] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server','PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Sitename')] [System.String] $Name, [switch]$PassThru, [PSCredential]$Credential = $script:PSIISCredential ) Begin {} Process { if ($_ -is [System.Object]) { $Site = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName) # Name = ($_.Sitename) ? $_.Sitename : $_.Name } If ($_.Server) { $Site['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Site['ComputerName'] = $_.ComputerName } Else { $Site['ComputerName'] = $_.PSComputerName } } If ($_.Sitename) { $Site['Name'] = $_.Sitename } Else { $Site['Name'] = $_.Name } } else { $Site = @{ ComputerName = $ComputerName Name = $Name } } if ($PSCmdlet.ShouldProcess($Site.ComputerName, "Start site: $($Site.Name)")) { $ScriptBlock = { [CmdletBinding()] Param( $Site, [switch]$PassThru ) Import-Module WebAdministration Start-Website -Name $Site.Name -ErrorAction SilentlyContinue -PassThru:$PassThru } $Site.ComputerName | Foreach-Object { If (IsLocal $_) { & $ScriptBlock -Site $Site -PassThru:$PassThru } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Site, $PassThru) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } } } #EndRegion Start-PSIISSite #Region Stop-PSIISPool <# .SYNOPSIS Stop an application pool. .DESCRIPTION Supply the web server and application pool to recycle. .PARAMETER ComputerName Specify the remote server to run against. .PARAMETER Name Specify the pool name to recycle. .PARAMETER Sites Specify the site names that are tied to this pool. This parameter is meant to support Pipeline values, but is not required to specify manually. Example: $Pool | Stop-PSIISPool # $Pool will have Sites information and pass it through the pipeline. Stop-PSIISPool -ComputerName Server1 -Name Pool1 # No site information will be included.. .PARAMETER PassThru If true, the command will return the IIS information. .PARAMETER Credential The credentials to use for the connection. If not specified the connection will use the current user. You can provide a PSCredential object, or use `New-PSIISSession` to create a PSCredential object that lives for the current powershell session. See `Get-Help New-PSIISSession` for more details. .EXAMPLE PS> Stop-PSIISPool -ComputerName WebServer01 -Name DefaultSitePool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01 -Name DefaultSitePool | Stop-PSIISPool Description ----------- This will recycle the DefaultSitePool pool on WebServer01. .EXAMPLE PS> Get-AppPool -ComputerName WebServer01,WebServer02 | Stop-PSIISPool Description ----------- CAUTION: This will recycle ALL app pools on WebServer01 and WebServer02. .EXAMPLE PS> Get-WebsiteInformation url.matthewjdegarmo.com | Stop-PSIISPool Description ----------- If url.matthewjdegarmo.com is found, this will prompt to recycle the app pool it is using. You should only do this if you KNOW that this is the only site on the found Application Pool. .NOTES Author: matthewjdegarmo GitHub: https://github.com/matthewjdegarmo Sponsor: https://github.com/sponsors/matthewjdegarmo #> Function Stop-PSIISPool() { [CmdletBinding( SupportsShouldProcess, ConfirmImpact = "High" )] Param( [Parameter(ValueFromPipelineByPropertyName)] [Alias('Server', 'PSComputerName')] [System.String[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipelineByPropertyName)] [Alias('ApplicationPool')] [System.String] $Name, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Sitename', 'Applications')] [System.String[]] $Sites, [switch]$PassThru, [PSCredential]$Credential = $script:PSIISCredential ) Begin {} Process { #Region Dynamic Pipeline handling if ($_ -is [System.Object]) { $Pool = @{ # The below If Else statements are version of these Turnary commands. # Windows PowerShell can't handle turnary operators. Leaving these here for reference to the below logic. # ComputerName = ($_.Server) ? $_.Server : (($_.ComputerName) ? $_.ComputerName : $_.PSComputerName).ToUpper() # Name = ($_.ApplicationPool) ? $_.ApplicationPool : $_.Name # Sites = ($_.SiteName) ? $_.SiteName : (($_.Applications) ? $_.Applications : $_.Sites) } If ($_.Server) { $Pool['ComputerName'] = $_.Server } Else { If ($_.ComputerName) { $Pool['ComputerName'] = $_.ComputerName } Else { $Pool['ComputerName'] = $_.PSComputerName } } If ($_.ApplicationPool) { $Pool['Name'] = $_.ApplicationPool } Else { $Pool['Name'] = $_.Name } If ($_.SiteName) { $Pool['Sites'] = $_.SiteName } Else { If ($_.Applications) { $Pool['Sites'] = $_.Applications } Else { $Pool['Sites'] = $_.Sites } } } else { $Pool = @{ ComputerName = $ComputerName.ToUpper() Name = $Name } If ($Sites) { $Pool['Sites'] = $Sites.ToUpper() } else { $Pool['Sites'] = (Get-PSIISPool -ComputerName $Pool.ComputerName -Name $Pool.Name).Applications } } #EndRegion Dynamic Pipeline handling if ($PSCmdlet.ShouldProcess($Pool.ComputerName, "Stop $($Pool.Name) pool containing sites: $($Pool.Sites)")) { $ScriptBlock = { [CmdletBinding()] Param( $Pool, [switch]$PassThru ) Write-Verbose "$($Pool.ComputerName): Stopping Pool: $($Pool.Name)" Import-Module WebAdministration Stop-WebAppPool -Name $Pool.Name -ErrorAction SilentlyContinue -PassThru:$PassThru # Get-PSIISPool -Name $Pool.Name -State 'Stopped' } If (IsLocal $Pool.ComputerName) { & $ScriptBlock -Pool $Pool -PassThru:$PassThru } Else { $InvokeCommandSplat = @{ ComputerName = $_ ScriptBlock = $ScriptBlock ArgumentList = @($Pool, $PassThru) } If ($null -ne $Credential) { $InvokeCommandSplat['Credential'] = $Credential } Invoke-Command @InvokeCommandSplat | Select-Object * -ExcludeProperty RunspaceID } } } } #EndRegion Stop-PSIISPool |