Set idleTimeoutAction from octopus - powershell

I am working on building scripts to set my startMode and idleTimeoutAction from octopus. My script is changing the startMode correctly, but I keep getting errors with the idleTimeoutAction. Can someone help me?
Here is the error i'm getting:
Executing script on 'APPSWDEV01' Setting LeadsAPI property startMode
to AlwaysRunning Old value AlwaysRunning New value AlwaysRunning Done
Setting LeadsAPI property idleTimeoutAction to Suspend
System.ArgumentException: Property ("idleTimeoutAction") is not found
on \APPSWDEV01\AppPools\LeadsAPI. Parameter name:
providerSpecificPickList at
Microsoft.IIs.PowerShell.Provider.ConfigurationProvider.GetProperty(String
path, Collection`1 providerSpecificPickList) There was a problem
setting property
# Running outside octopus
param(
[string]$APIName,
[switch]$whatIf
)
$ErrorActionPreference = "Stop"
function Get-Param($Name, [switch]$Required, $Default) {
$result = $null
if ($OctopusParameters -ne $null) {
$result = $OctopusParameters[$Name]
}
if ($result -eq $null) {
$variable = Get-Variable $Name -EA SilentlyContinue
if ($variable -ne $null) {
$result = $variable.Value
}
}
if ($result -eq $null -or $result -eq "") {
if ($Required) {
throw "Missing parameter value $Name"
} else {
$result = $Default
}
}
return $result
}
& {
param(
[string]$APIName
)
if (![string]::IsNullOrEmpty($APIName))
{
Write-Host "Setting $APIName property startMode to AlwaysRunning"
try {
Add-PSSnapin WebAdministration -ErrorAction SilentlyContinue
Import-Module WebAdministration -ErrorAction SilentlyContinue
$oldValue = Get-ItemProperty "IIS:\AppPools\$APIName" -Name "startMode"
$oldValueString = ""
if ($oldValue.GetType() -eq [Microsoft.IIs.PowerShell.Framework.ConfigurationAttribute])
{
$oldValueString = ($oldValue | Select-Object -ExpandProperty "Value");
}
else
{
$oldValueString = $oldValue
}
Write-Host "Old value $oldValueString"
Set-ItemProperty "IIS:\AppPools\$APIName" -Name "startMode" -Value "AlwaysRunning"
Write-Host "New value AlwaysRunning"
Write-Host "Done"
} catch {
Write-Host $_.Exception|format-list -force
Write-Host "There was a problem setting property"
}
Write-Host "Setting $APIName property idleTimeoutAction to Suspend"
try {
Add-PSSnapin WebAdministration -ErrorAction SilentlyContinue
Import-Module WebAdministration -ErrorAction SilentlyContinue
$oldValue = Get-ItemProperty "IIS:\AppPools\$APIName" -Name "idleTimeoutAction"
$oldValueString = ""
if ($oldValue.GetType() -eq [Microsoft.IIs.PowerShell.Framework.ConfigurationAttribute])
{
$oldValueString = ($oldValue | Select-Object -ExpandProperty "Value");
}
else
{
$oldValueString = $oldValue
}
Write-Host "Old value $oldValueString"
Set-ItemProperty "IIS:\AppPools\$APIName" -Name "idleTimeoutAction" -Value "Suspend"
Write-Host "New value Suspend"
Write-Host "Done"
} catch {
Write-Host $_.Exception|format-list -force
Write-Host "There was a problem setting property"
}
}
} `
(Get-Param 'APIName' -Required)

I had a look at the file C:\Windows\System32\inetsrv\config\applicationHost.config which contains app pool settings. When an idleTimeoutAction is manually configured on an application pool, the result is an entry like:
<add name="MyAppPool" managedRuntimeVersion="v4.0">
<processModel idleTimeoutAction="Suspend" />
</add>
From PowerShell you can access the idleTimeoutAction property via the command:
Get-ItemProperty "IIS:\AppPools\MyAppPool" -Name processModel.idleTimeoutAction
Likewise, you can set the idleTimeoutAction property via:
Set-ItemProperty "IIS:\AppPools\MyAppPool" -Name processModel.idleTimeoutAction -Value "Suspend"
Hope this helps.

Related

PowerShell get output in CSV format

I am seeking help to get output in csv format. I have written powershell code and would want to tweak the output to get in csv format as shown in below pic.
$servers = Get-Content 'C:\Temp\listofservers.txt'
foreach ($server in $servers)
{
#DHCP
if (((Get-Service -ComputerName $server -ServiceName 'DHCPServer' -ErrorAction SilentlyContinue).Status) -eq 'Running')
{
if ((((Get-DhcpServerv4Scope -ComputerName $server | Get-DhcpServerv4Lease -ComputerName $server) | Measure-Object).Count) -ge 1)
{
Write-Host "DHCP present on $server and in use"
}
else
{
Write-Host "DHCP present on $server and not in use"
}
}
else
{
Write-Host("DHCP is not present on $server")
}
#Certificate authority
if (((Get-Service -ComputerName $server -ServiceName 'CertSvc' -ErrorAction SilentlyContinue).Status) -eq 'Running')
{
Write-Host "Certificate Authority is present on $server"
}
else
{
Write-Host "Certificate Authority is not present on $server"
}
}
Send all outputs to a custom object then export them:
$servers = get-content "C:\Temp\listofservers.txt"
$ExportPath = 'c:\temp\results.csv'
$Servers | ForEach-Object {
Write-Host "Checking $_"
# DHCP status
# Use Try....Catch to trap the errors - it's more robust than
# If...Then and prevents a wall of red text if something goes wrong
Try {
$DHCPStatus = Get-Service -ComputerName $_ -Name 'DHCPServer' -ErrorAction Stop
If ($DHCPStatus.Status -eq "Running") {
Try {
If ((((Get-DhcpServerv4Scope -ComputerName $_ -ErrorAction Stop | Get-DhcpServerv4Lease -ComputerName $_ -ErrorAction Stop) | Measure-Object).Count) -ge 1) {
$DHCPResult = "DHCP present on, in use"
}
Else {
$DHCPResult = "DHCP present, not in use"
}
}
Catch {
$DHCPResult = "DHCP present - error obtaining details: $_"
}
}
}
Catch {
$DHCPResult = "DHCP is not present"
}
#Certificate authority
Try {
If (((Get-Service -ComputerName $_ -ServiceName 'CertSvc' -ErrorAction Stop).Status) -eq "Running") {
$CAResult = "Certificate Authority is present"
}
}
Catch {
$CAResult = "Certificate Authority is not present"
}
[pscustomobject]#{ComputerName = $_;DHCP = $DHCPResult;CA=$CAResult}
} | Export-Csv -Path $ExportPath -NoTypeInformation
Use a hashtable to build your object, adding key/values for each property along the way. Then convert the hashtable to a [PSCustomObject] and output it capturing in a variable ($results). Finally, export it to csv using Export-Csv
$servers = Get-Content 'C:\Temp\listofservers.txt'
$results = foreach ($server in $servers) {
# Create hashtable to build object and add ComputerName property
$output = [ordered]#{ComputerName = $server }
#DHCP
if (((Get-Service -ComputerName $server -ServiceName 'DHCPServer' -ErrorAction SilentlyContinue).Status) -eq 'Running') {
if ((((Get-DhcpServerv4Scope -ComputerName $server |
Get-DhcpServerv4Lease -ComputerName $server) |
Measure-Object).Count) -ge 1) {
# add Dhcp property if present, in use
$output.Add('Dhcp', 'Present, in use')
}
else {
# add Dhcp property if present, not in use
$output.Add('Dhcp', 'Present, not in use')
}
}
else {
# add Dhcp property if not present
$output.Add('Dhcp', 'Not present')
}
#Certificate authority
if (((Get-Service -ComputerName $server -ServiceName 'CertSvc' -ErrorAction SilentlyContinue).Status) -eq 'Running') {
# add CA property if present
$output.Add('CA', 'Present')
}
else {
# add CA property if not present
$output.Add('CA', 'Not present')
}
# Convert hashtable to pscustomobject and output it
[PSCustomObject]$output
}
# output results to screen
$results
# export results to csv file
$results | Export-Csv -Path c:\temp\server_dhcp_ca_check.csv -NoTypeInformation

PowerShell: Invoke-Command with Try-Catch

I'm using the following code to give me output on the status of a batch of computers:
$Win2k8r2Computers = "Server1", "Server2", "Server3", "Server4"
$results = Invoke-Command -ComputerName $Win2k8r2Computers { #}
$props = #{}
Try {
<#If ($PSVersionTable.PSVersion.Major -eq "2") {
$props.Add('Message',"Server (Win2008r2) is currently running an incompatible version of PowerShell (v2.1)")
}#>
If (Get-Service | Where-Object { $_.Name -eq "W3SVC" } -ErrorAction Stop) {
$props.Add('Message', "IIS is installed (Win2008r2)")
}
Else {
$props.Add('Message', "IIS is NOT installed (Win2008r2)")
}
}
catch {
$props.Add('Message', 'Error: {0}' -f $_)
}
New-Object -Type PSObject -Prop $Props
}
It's working as expected other than the catch not appearing to actually catch and return errors to the $results variable. What am I missing?
In your current code, you are passing parameter -ErrorAction only to Where-Object. So you would only catch errors of the Where-Object cmdlet. Get-Service woud still run with the default ErrorAction value of Continue.
To turn errors of both Get-Service and Where-Object into terminating errors that can be catched, either pass -ErrorAction 'Stop' to both of them...
If (Get-Service -ErrorAction Stop | Where-Object { $_.Name -eq "W3SVC" } -ErrorAction Stop)
... or (more efficiently) set the $ErrorActionPreference variable at the beginning of the script and remove the -ErrorAction parameter:
$Win2k8r2Computers = "Server1", "Server2", "Server3", "Server4"
$results = Invoke-Command -ComputerName $Win2k8r2Computers { #}
$props = #{}
Try {
$ErrorActionPreference = 'Stop'
<#If ($PSVersionTable.PSVersion.Major -eq "2") {
$props.Add('Message',"Server (Win2008r2) is currently running an incompatible version of PowerShell (v2.1)")
}#>
If (Get-Service | Where-Object { $_.Name -eq "W3SVC" }) {
$props.Add('Message', "IIS is installed (Win2008r2)")
}
Else {
$props.Add('Message', "IIS is NOT installed (Win2008r2)")
}
}
catch {
$props.Add('Message', 'Error: {0}' -f $_)
}
New-Object -Type PSObject -Prop $Props
}
Caveat:
$ErrorActionPreference is ignored by cmdlets in PowerShell script modules, unless they take special care of handling it.
See this answer for some insight.
In this case it works though, because both cmdlets are implemented in C# modules.

Script is not picking all servers from the text file

$Servers = Get-Content "D:\Server\Servers.txt"
#Gathering Vars
$OSVersion = (Get-CimInstance Win32_OperatingSystem).version
$WarningPreference = 'SilentlyContinue'
$key = 'HKLM:\Software\Company\SCCMMetaData'
$StampCheck = (Get-ItemProperty -Path $key).PatchRelease
$data = foreach ($server in $Servers) {
#Gathering OS Version & Normalization of data
If ($OSVersion -like "10.*") { $OSName = "WINS2016-"; $KB = "KB4540670", "KB4538461", "KB4550929", "KB4556813", "KB4549949", "KB4550994", "KB4494175", "KB4540723" }
Elseif ($OSVersion -like "6.0.*") { $OSName = "WINS08R1-"; $KB = "KB4534303", "KB4534312" }
Elseif ($OSVersion -like "6.1.*") { $OSName = "WINS08R2-"; $KB = "KB4534314", "KB4539602", "KB4534310" }
Elseif ($OSVersion -like "6.2.*") { $OSName = "WINS12R1-"; $KB = "KB4541510", "KB4550917", "KB4556840", "KB4540726" }
Elseif ($OSVersion -like "6.3.*") { $OSName = "WINS12R2-"; $KB = "KB4541509", "KB4550961", "KB4556846", "KB4540725" }
#Check to see if KB is installed & build the stamp
Try {
$KBSearch = Get-HotFix -id $KB -ErrorAction Stop
$Stamp = $OSName
If ($StampCheck -eq "2020Q2") {
Return "$Server Already Compliant"
}
Else {
Set-ItemProperty -path 'HKLM:\Software\Company\SCCMMetaData' -Name 'PatchRelease' -Value $Stamp
Restart-Service -DisplayName 'Agent' -ErrorAction Ignore
Start-Sleep 30
Return "$Server Stamped"
}
}
Catch { Return "Missing Patch $KB on server $Server" }
}
Restart-Service -DisplayName ' Agent'
$data | Export-Csv "D:\Scripts\KB.csv" -NoTypeInformation
This is my code and it is not iterating for all the servers in the .txt file. It is only taking 1st server in the list .
It is not checking for each server in the txt file . Where i am doing the mistake ? Could any one help me ?
return will cause PowerShell to... well, return control to the caller :)
Simply omit the return keyword and leave the expressions following them as-is - they'll automatically "bubble up" to the caller anyway:
#Check to see if KB is installed & build the stamp
Try {
$KBSearch = Get-HotFix -id $KB -ErrorAction Stop
$Stamp = $OSName
If ($StampCheck -eq "2020Q2") {
"$Server Already Compliant"
}
Else {
Set-ItemProperty -path 'HKLM:\Software\Company\SCCMMetaData' -Name 'PatchRelease' -Value $Stamp
Restart-Service -DisplayName 'Agent' -ErrorAction Ignore
Start-Sleep 30
"$Server Stamped"
}
}
Catch { "Missing Patch $KB on server $Server" }
You can read more about the return keyword in the about_Return helpfile

Powershell I don't get the log to work

I have recently started with Powershell and I have been trying to use it as much as I can, but I get quite frustrated.
I have this code which does what I want, but the log doesn't work but I don't get errors:
Function logWrite
{
param ([string]$logstring)
$Computer = gc env:computername
$date = $(Get-Date -UFormat "%d-%m-%Y")
$Logfile = C:\Windows\Temp\Key-KB-Testing-$Computer-$date.log
Add-content -Path $Logfile -Value $logstring
}
$Stamp = (Get-Date).toString("dd/MM/yyyy HH:mm:ss")
logWrite "Testing KB3142037"
$KB3142037result= gwmi -cl win32_reliabilityRecords -filter "sourcename = 'Microsoft-Windows-WindowsUpdateClient'" | where { $_.message -match 'KB3142037'} | select -Expand Message
logWrite $Stamp
logWrite "Testing KB3142033"
$KB3142033result= gwmi -cl win32_reliabilityRecords -filter "sourcename = 'Microsoft-Windows-WindowsUpdateClient'" | where { $_.message -match 'KB3142033'} | select -Expand Message
logWrite $Stamp
$Key = Get-ItemProperty HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319\ -Name SchUseStrongCrypto | Select-Object -ExpandProperty SchUseStrongCrypto
$arquitecture = (gwmi win32_computersystem).SystemType
If ($arquitecture -eq "x32-based PC")
{
If ($Key -eq $true)
{
logWrite "The key exist and the value is '$Key'"
if ($Key -ne "0")
{
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '0' -Type DWord -ErrorAction SilentlyContinue -Verbose
logWrite "The key has been modified"
logWrite $Stamp
}
}
Else {
logWrite "There is no key. New registry key will be created"
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319 -Name SchUseStrongCrypto -PropertyType DWord -Value 0 -ErrorAction SilentlyContinue -Verbose
logWrite $Stamp
logWrite "The Key has been created"
}
}
Else
{
If ($Key -eq $true)
{
logWrite "The key exist and the value is '$Key'"
if ($Key -ne "0")
{
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '0' -Type DWord -ErrorAction SilentlyContinue -Verbose
logWrite "The key has been modified"
logWrite $Stamp
}
}
Else {
logWrite "There is no key. New registry key will be created"
New-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319 -Name SchUseStrongCrypto -PropertyType DWord -Value 0 -ErrorAction SilentlyContinue -Verbose
logWrite $Stamp
logWrite "The Key has been created"
}
}
Any help, links or guidance will be helpfull.
Thanks in advance for your time.
Regards
Try
$Logfile = "C:\Windows\Temp\Key-KB-Testing-$Computer-$date.log"

How can I catch Browsererrors like 504 in a SharePoint2013 Warm-Up Skript?

I am a freshman at PowerShell and I try to implement a SharePoint Warm-Up Skript.
This Skript is not originally mine, i only edited a existing one. Now it run nicely. But if a error occured like a DNS look up fail i want a Output in my Logfile like: "A DNS look up fail occured at URL..."
I want to catch the Browsererrors 400, 404 and 504. How can I catch them?
Here my code so far:
Function WarmUp() {
# Get URL list
Add-PSSnapIn Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$was = Get-SPWebApplication -IncludeCentralAdministration
$was |? {$_.IsAdministrationWebApplication -eq $true} |% {$caTitle = Get-SPWeb $_.Url | Select Title}
# Warm up SharePoint web applications
Write-Host "Opening Web Applications..."
$global:ie = New-Object -Com "InternetExplorer.Application"
$global:ie.Navigate("about:blank")
$global:ie.Visible = $true
$global:ieproc = (Get-Process -Name iexplore)|? {$_.MainWindowHandle -eq $global:ie.HWND}
#Navigate here to all Applications, Collections and sites
# Close IE window
if ($global:ie) {
Write-Host "Closing IE"
$global:ie | Stop-Process -Force -ErrorAction SilentlyContinue
}
$global:ieproc | Stop-Process -Force -ErrorAction SilentlyContinue
# Clean Temporary Files
Remove-item "$env:systemroot\system32\config\systemprofile\appdata\local\microsoft\Windows\temporary internet files\content.ie5\*.*" -Recurse -ErrorAction SilentlyContinue
Remove-item "$env:systemroot\syswow64\config\systemprofile\appdata\local\microsoft\Windows\temporary internet files\content.ie5\*.*" -Recurse -ErrorAction SilentlyContinue
}
Function IENavigateTo([string] $url, [int] $delayTime = 500) {
# Navigate to a given URL
if ($url) {
if ($url.ToUpper().StartsWith("HTTP")) {
Write-Host " Navigating to $url"
try {
$global:ie.Navigate($url)
#If the certificate is invalid, bypass the error to show the context.
if ($global:ie.document.url -Match "invalidcert")
{
"Bypassing SSL Certificate Error Page";
$sslbypass=$global:ie.Document.getElementsByTagName("a") | where-object {$_.id -eq "overridelink"};
$sslbypass.click();
"Sleep for 5 seconds while final page loads";
start-sleep -s 5;
}
} catch {
try {
$pid = $global:ieproc.id
} catch {}
Write-Host " IE not responding. Closing process ID $pid"
$global:ie | Stop-Process -Force -ErrorAction SilentlyContinue
$global:ieproc | Stop-Process -Force -ErrorAction SilentlyContinue
$global:ie = New-Object -Com "InternetExplorer.Application"
$global:ie.Navigate("about:blank")
$global:ie.Visible = $true
$global:ieproc = (Get-Process -Name iexplore)|? {$_.MainWindowHandle -eq $global:ie.HWND}
}
IEWaitForPage $delayTime
}
}
}
Function IEWaitForPage([int] $delayTime = 500) {
# Wait for current page to finish loading
$loaded = $false
$loop = 0
$maxLoop = 20
while ($loaded -eq $false) {
$loop++
# Wait until the page is loaded.
While ($global:ie.ReadyState -ne 4) {
Start-Sleep -Seconds 2
Write-Host "Busy!"
}
if ($loop -gt $maxLoop) {
$loaded = $true
}
[System.Threading.Thread]::Sleep($delayTime)
# If the browser is not busy, the page is loaded
if (-not $global:ie.Busy)
{
$loaded = $true
}
}
}
#Main
if(-not(Test-Path "C:\Logs\SharePoint\WarmUpLogTest")){New-Item -ItemType Directory -Path "C:\Logs\SharePoint\WarmUpLogTest"}
Start-Transcript -Path ("C:\Logs\SharePoint\WarmUpLogTest\SPWarmUp{0:yyyy-MM-dd}.txt" -f $(get-date)) -Append
WarmUp
Stop-Transcript
If you run powershell V3 or newest you can add this on top of your IENavigateTo
try{invoke-webrequest $url}
catch{$_.errordetails|select -expand message}
without V3 you can try something like
$request = [System.Net.WebRequest]::Create($url)
try{$response = $request.GetResponse() }catch{$_.exception.message}