Powershell I don't get the log to work - powershell

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"

Related

how to use variable out of invoke-command in powershell?

I have below Invoke-command code, the script using hponcfg.exe file on remote server to get ILO configuration. few servers having issue with power capping and error returned by hponcfg.exe as
"Message = 0x0089 Power capping information is not available at this time, try again later."
My question is: I want to capture this error if generated by hponcfg inside invoke-command scriptblock and use it out of scriptblock.
$CurrentDir = (Split-Path $invocation.MyCommand.Path).ToLower()
$CurrentDir
$Credential = get-credential -message "Please supply SA account details."
$servers = gc .\servers.txt
#$Global:ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$date = (get-date).ToString("yyyyMMdd_HHmm")
$ILOContent = ".\ILOConfigData_$date.csv"
New-Item -path $ILOContent -type file -Force | out-null
Add-Content -Path $ILOContent -Value "ILO_Name,Model,ILOFIrmware,ILODevice,ILOFWDate,ILO_Domain,Network_Details,ILO_TimeZone,Directory_Users,LDAP_Directory_Authentication,Directory_Groups,SNMP_Settings,Directory_Server_Address"
Foreach($server in $servers){
if (Test-Connection -ComputerName $server -Quiet)
{
#$Frompath = ".\ILO_Prerequisite\"
#$To_Path = "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$tmp="Drv_$server"
new-psdrive $tmp filesystem "\\$server\C$" -cred $cred|Out-Null
$Model = (Get-WmiObject -ComputerName $server -Class:Win32_ComputerSystem).model
Write-Host "Validating HPE pre-requisites on server:"$server -BackgroundColor DarkGray -ForegroundColor White
if (-not(test-path("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")))
{
Write-Host "Corrupt 'HPONCFG' folder structure found. Remediating, will take few seconds." -ForegroundColor Red
New-Item -Path ("$($tmp):\Program Files\Hewlett Packard Enterprise\") -ItemType Directory -Name HPONCFG -Force|Out-Null
$To_Path =("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")
$From_Path = ".\ILO-PreRequisite\*"
copy-item -path $From_Path -Destination $To_Path -recurse -Force
Sleep(6)
Write-Host "'HPONCFG' folder structure remediated." -ForegroundColor Green
}
Elseif (-not(test-path("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe")))
{
$To_Path =("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")
Write-Host "Corrupt 'HPONCFG' folder structure found. Remediating, will take few seconds." -ForegroundColor Red
copy-item -path $From_Path -Destination $To_Path -recurse -Force
Sleep(6)
Write-Host "'HPONCFG' folder structure remediated" -ForegroundColor Green
}
remove-psdrive -name $tmp -force
#if (-not(test-path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe"))
# {
# do copy job
# write-host "Copying files and folders from $frompath to $topath" -ForegroundColor Yellow
# copy-item -path $frompath -Destination $topath -recurse
# }
$export = Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {
New-Item -Path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG" -ItemType File -Name Current_ILOConfig.xml -Force| Out-Null
Set-Location "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$ILODataPath = Get-Location
$WantFile = "$ILODataPath\Current_ILOConfig.txt"
$FileExists = Test-Path $WantFile
If ($FileExists -eq $True) {Remove-Item $WantFile }
Sleep(2)
Write-Host "Gathering current ILO configuration for $ENV:COMPUTERNAME" -ForegroundColor Yellow
& "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
"C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" |Out-Null
Get-Content .\Current_ILOConfig.xml
}
$export|Out-File "Current_ILOConfig.txt"
Sleep(3)
$ILORAW_DATA = Get-Content .\Current_ILOConfig.txt
$ILORAW_DATA|ForEach-Object{
$_ -replace '<!-- ' `
-replace ' -->' `
-replace '<' `
-replace ' />' `
-replace '"' `
}|Set-Content .\Current_ILOConfig.txt
$ILO_DATA = Get-Content .\Current_ILOConfig.txt
Write-Host "Getting ILO DNS details"
$DNS_NAME = $ILO_DATA |Where {$_ |Select-String -Pattern " DNS_NAME VALUE"," DOMAIN_NAME VALUE"}
$ILONAME = $DNS_NAME -split "="
$ILO_Name = $ILONAME[1]
$ILO_Domain = $ILONAME[3]
Write-Host "Getting ILO Network details"
$NT = $ILO_DATA | where {$_ |Select-String -Pattern " IP_ADDRESS VALUE"," SUBNET_MASK"," GATEWAY_IP_ADDRESS"," PRIM_DNS_SERVER VALUE", " SEC_DNS_SERVER VALUE"," TER_DNS_SERVER VALUE" }
$Network = [array]$NT -join "`n"
$Network_Details = $Network.Trim()
Write-Host "Getting ILO TimeZone"
$TZ= $ILO_DATA |Where {$_ | Select-String -Pattern " TIMEZONE VALUE"}
$TimeZone =$TZ -Split "="
$ILO_TimeZone = $TimeZone[1]
Write-Host "Getting ILO Directory Server Address" # Directory_Server_Address
$DSA = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_SERVER_ADDRESS"}
$DIR_SERVERADDRESS = $DSA -Split "="
$Directory_Server_Address = $DIR_SERVERADDRESS[1]
$ILODeviceID = #()
$ILODev = $ILO_DATA|where{$_|Select-String -Pattern "Device: "}
$ILODevStr = $ILODev -split(' ')
$ILODeviceID += $ILODevStr[1..2] -as [string]
$ILODeviceID += $ILODevStr[7]
$ILODeviceID += $ILODevStr[-1]
Write-Host "Getting LDAP Directory Authentication Enabled/Disabled?"
$LDAP_DIR = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_AUTHENTICATION_ENABLED"}
$LDAP_DIR_STATUS = $LDAP_DIR -split "="
$LDAP_Directory_Authentication = $LDAP_DIR_STATUS[1]
Write-Host "Getting ILO Device detail"
$ILOFIrmware = $ILODevStr[7]
Write-Host "Getting ILO Firmware Version"
$ILODevice = $ILODevStr[1,2]
Write-Host "Getting ILO Firmware Version date"
$ILOFWDate = $ILODevStr[-1]
Write-Host "Getting SNMP Settings" #SNMP_Settings
$SNMPADDRESS = $ILO_DATA |Where {$_ | Select-String -Pattern "SNMP_ADDRESS"}
$SNMP_DATA = #()
foreach($SNMP in $SNMPADDRESS)
{
$SNMP_DATA +=($SNMP -split "VALUE=")[1]
}
$SNMP_Settings = $SNMP_DATA -join "`n"
Write-Host "Getting ILO Directory User details"
$DIR_USER = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_USER_CONTEXT"}
$User =#()
foreach($Usr in $DIR_USER)
{
$User += ($Usr -split "VALUE=")[1]
}
#$User
$Directory_Users = $User -join "`n"
#group Account details
Write-Host "Getting ILO Directory Group details"
$DIR_GRPACCT = $ILO_DATA |Where {$_ | Select-String -pattern " DIR_GRPACCT"}
$ACCTs = #()
for($a=1;$a -le 10;$a++)
{
$GroupName = "DIR_GRPACCT" + $a + "_NAME"
#$Privilege = "DIR_GRPACCT" + $a + "_PRIV"
$DIR_GRPACCT = $ILO_DATA |Where {$_ | Select-String -pattern $groupname}
foreach ($acct in $DIR_GRPACCT)
{
$ACCTS += ($acct -split "VALUE=")[1]
}
$DIR_GRPACCTS = ($ACCTS -join "`n")
}
$data = "`"$ILO_Name`",`"$Model`",`"$ILOFIrmware`",`"$ILODevice`",`"$ILOFWDate`",`"$ILO_Domain`",`"$Network_Details`",`"$ILO_TimeZone`",`"$($Directory_Users.trimend())`",`"$LDAP_Directory_Authentication`",`"$($DIR_GRPACCTS.trimend())`",`"$($SNMP_Settings.trimend())`",`"$($Directory_Server_Address.trimend())`""
$Data |Out-File -Append $ILOContent
}
else
{
write-host -ForegroundColor Red "Server $server is not reachable"
$data = "`"$server`",`"not reachable`""
$Data |Out-File -Append $ILOContent
}
}
#Clear User defined variables
Write-Host "Performing Clean-up" -ForegroundColor Yellow
#Clear-Variable -Name ILO*
Function Get-ScriptVariable ($Name = '*')
{
# these variables may exist in certain environments (like ISE, or after use of foreach)
$special = 'ps','psise','psunsupportedconsoleapplications', 'foreach', 'profile'
$ps = [PowerShell]::Create()
$null = $ps.AddScript('$null=$host;Get-Variable')
$reserved = $ps.Invoke() |
Select-Object -ExpandProperty Name
$ps.Runspace.Close()
$ps.Dispose()
Get-Variable -Scope Global |
Where-Object Name -like $Name |
Where-Object { $reserved -notcontains $_.Name } |
Where-Object { $special -notcontains $_.Name } |
Where-Object Name
}Get-ScriptVariable|Out-Null
Get-ScriptVariable |Clear-Variable ;Write-Host "Clean-up completed." -ForegroundColor Green
Write-Host "Check detailed log stored at path: "$CurrentDir -ForegroundColor Green```
You can use try-catch-finally method to get your error messages.
Hi I have modified your script invoke-command part only. Please test and use it. This script is not tested.
$export = Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {
try {
New-Item -Path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG" -ItemType File -Name Current_ILOConfig.xml -Force | Out-Null
Set-Location "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$ILODataPath = Get-Location
$WantFile = "$ILODataPath\Current_ILOConfig.txt"
$FileExists = Test-Path $WantFile
If ($FileExists -eq $True) { Remove-Item $WantFile }
Sleep(2)
Write-Host "Gathering current ILO configuration for $ENV:COMPUTERNAME" -ForegroundColor Yellow
& "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
"C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" | Out-Null
Get-Content .\Current_ILOConfig.xml
}
catch {
return $_
}
}
$export | Out-File "Current_ILOConfig.txt"

Why is my if statement not being read properly?

I have a script that backs up a user profile from the local, or remote machine and places it onto a share: $Global:Shared_BackupPath = "\\server\share\". I've been tweaking it a little more and just ended up making some variables into Global variables (not sure if this is the issue - dont see why it would be).
This is the condition:
if(-not (Get-EventSubscriber)){
I tried changing it to -eq $null to see if it would make any difference, but it didn't.
Its just not analyzing the condition properly and goes on to display my message box before all Jobs are done: it's "supposed" to wait till there's no more events and then display the message box:
Register-ObjectEvent -InputObject $job -EventName StateChanged -Action {
#Start-Sleep -Milliseconds 500
$eventSubscriber | Unregister-Event
$eventSubscriber.Action | Remove-Job
if(-not (Get-EventSubscriber)){
$Profile_Sum = Get-ChildItem -Path $Global:BackUp_Path -Recurse |
Measure-Object -Property length -Sum |
Select-Object -ExpandProperty Sum
$Size = try{if($Profile_Sum -lt 1048576){ $TinyByte = " {0:N2}" -f ($Profile_Sum / 1KB) + " KB"; $TinyByte }
elseif($Profile_Sum -gt 1048576 -and $Profile_Sum -lt 1073741824){ $MediumByte = " {0:N2}" -f ($Profile_Sum / 1MB) + " MB"; $MediumByte }
elseif($Profile_Sum -gt 1073741824){ $GiganticByte = " {0:N2}" -f ($Profile_Sum / 1GB) + " GB"; $GiganticByte } } Catch {}
$Begin_Time = Get-Item -Path $Global:BackUp_Path | Select-Object -ExpandProperty LastWriteTime
$End_Time = Get-Date -Format G
Get-Job | Remove-Job
[System.Windows.MessageBox]::Show("Copying Complete!`nStart Time: $Begin_Time `nEnd Time: $End_Time `nProfile Size copied: $Size")
}
} | Out-Null
}
I feel like I may have an idea due to the event itself being registered as a job but, not too sure how to go about it and have it wait until its done with ALL jobs before displaying the messagebox informing me when the copying is complete. Other than that, the script works just fine and anyone reading this can feel free to use it themselves. Heres the full Script:
Function PFL-UserBackUp{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$false,
ValueFromPipeLine=$true,
ValueFromPipeLineByPropertyName=$true)]
[Alias('CN','Computer','server','node')]
[ValidateLength(1, 15)]
[String[]]$ComputerName = $env:COMPUTERNAME )
Begin{
$Global:Shared_BackupPath = "\\server\share\"
}
Process{
Foreach($Computer in $ComputerName){
Try{
$PSSession = New-PSSession -ComputerName $Computer -ErrorAction Stop
[array]$User_List = Invoke-Command -ScriptBlock {
Get-ChildItem -Path "C:\Users" -Exclude Public, Default* |
Sort-Object -Property LastWriteTime -Descending } -Session $PSSession
$userinfo1 = foreach ($user in $User_List.name) {
$userinfo = (net user $user /domain | Select-String "Full Name" -ErrorAction SilentlyContinue) -replace "Full Name ", "" 2>&1 | Out-String -Stream
if ($userinfo.Length -lt 4) { "NO DISPLAY NAME in ADUC" }
elseif($LASTEXITCODE -eq 2) { "ACCOUNT NOT in ADUC" }
elseif($LASTEXITCODE -eq 0) { $userinfo }
else { "Error occured" }
}
$(for($i=0; $i -lt $User_List.Count; $i++){
[pscustomobject]#{
'User Display Name ' = "$($i): $($userinfo1[$i])"
' NAME ' = $User_List.name[$i]
'Last Modified' = "$($User_List.LastWriteTime[$i])"
'Profile Size ' = Try{
$ProfilePath = $User_List.FullName[$i]
$Profile_Sum = Invoke-Command -ScriptBlock {
Get-ChildItem -Path $Using:ProfilePath -Recurse |
Where-Object {$_.PSParentPath -match "Documents|Desktop|Music|Videos|Downloads|Links|Pictures|Favorites|Contacts" -and $_.DirectoryName -notmatch "OneDrive" } |
Measure-Object -Property length -Sum |
Select-Object -ExpandProperty Sum } -Session $PSSession
if($Profile_Sum -lt 1048576){ $TinyByte = " {0:N2}" -f ($Profile_Sum / 1KB) + " KB"; $TinyByte }
elseif($Profile_Sum -gt 1048576 -and $Profile_Sum -lt 1073741824){ $MediumByte = " {0:N2}" -f ($Profile_Sum / 1MB) + " MB"; $MediumByte }
elseif($Profile_Sum -gt 1073741824){ $GiganticByte = " {0:N2}" -f ($Profile_Sum / 1GB) + " GB"; $GiganticByte } #Profile Size
} Catch { "$($Error[0].Exception.Message.Split('.')[2].Trim())!" }
}
} ) | Out-Host
Write-Host "Press 'Q' to quit."
$ii = Read-Host -Prompt "Enter Number of Profile to Back-Up"
$i = $ii.Trim() -split ","
if([String]::IsNullOrEmpty($i) -eq $true) { "Null string"; Break }
elseif($i.ToLower() -like "q*") {"Q was selected. Stopping script."; Break }
<#
" "
" Following Profiles will be Saved:"
" ------------------------------------"
foreach($i in $index) { "$($i.trim()): $($userinfo1[$i])" }
" "
$Confirm = Read-Host -Prompt "Are you sure you want to continue? [Y/N]"
if($Confirm.ToLower().TrimStart() -like "n*" -or $Confirm.ToLower() -like "q*"){Break}
if([String]::IsNullOrEmpty($Confirm.Trim()) -eq $true) { "Null string"; Break }#>
$Profile_Path = "C:\Users\$($User_List.name[$i])"
$Literal_Name = $userinfo1[$i].Replace('/','-')
$Global:BackUp_Path = "$Global:Shared_BackupPath$Literal_Name"
$Test_Path = Test-Path -Path $Global:BackUp_Path
if($Test_Path -eq $false){
New-Item -Path $Global:BackUp_Path -ItemType Directory | Out-Null
Start-Process $Global:BackUp_Path}
elseif($Test_Path -eq $true){
$Find_OldName = Get-ChildItem -Path "$Global:Shared_BackupPath" -Filter "$Literal_Name" -Directory |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -ExpandProperty BaseName -First 1
$New_PathName = $Find_OldName + "1"
New-Item -Path "$Global:Shared_BackupPath" -Name $New_PathName -ItemType Directory -OutVariable Global:BackUp_Path | Out-Null #Global:BackUp_Path variable declared
$Global:BackUp_Path = $Global:BackUp_Path.FullName
Start-Process $Global:BackUp_Path}
$Global:Start_Time = Get-Date -Format G
#Favorites Copy
$FireFox_Favorites = "C:\Users\$($User_List.name[$i])\AppData\Roaming\Mozilla\Firefox\Profiles\*.default\places.sqlite"
$Chrome_Favorites = "C:\Users\$($User_List.name[$i])\AppData\Local\Google\Chrome\User Data\Default\Bookmarks"
$Chrome_Favorites2 = "C:\Users\$($User_List.name[$i])\AppData\Local\Google\Chrome\User Data\Default\Bookmarks.bak"
$Sticky_Notes = "C:\Users\$($User_List.name[$i])\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite"
$Favorites_Array = #($FireFox_Favorites,$Chrome_Favorites,$Chrome_Favorites2,$Sticky_Notes)
Foreach($File in $Favorites_Array){
$Test_File = Invoke-Command -ScriptBlock { Test-Path -Path $File }
if($Test_File -eq $true){
Copy-Item -Path $File -Destination $Global:BackUp_Path -Force -Recurse -FromSession $PSSession
}
}
#Folders Copy
$Folders = #('Desktop','Documents','Favorites','Links','Downloads','Music','Videos','Pictures','Contacts')
Foreach($Folder in $Folders){
#Create Arugments for seperate thread
$ArgumentsArray = $null
$ArgumentsArray = #()
$ArgumentsArray += "\\$Computer\c$\Users\$($User_List.name[$i])\$Folder"
$ArgumentsArray += $Global:BackUp_Path
$job = Start-Job -ScriptBlock { Copy-Item -Path $args[0] -Destination $args[1] -Force -Recurse } -Name $Folder -ArgumentList $ArgumentsArray
Register-ObjectEvent -InputObject $job -EventName StateChanged -Action {
#Start-Sleep -Milliseconds 500
$eventSubscriber | Unregister-Event
$eventSubscriber.Action | Remove-Job
if(-not (Get-EventSubscriber)){
$Profile_Sum = Get-ChildItem -Path $Global:BackUp_Path -Recurse |
Measure-Object -Property length -Sum |
Select-Object -ExpandProperty Sum
$Size = try{if($Profile_Sum -lt 1048576){ $TinyByte = " {0:N2}" -f ($Profile_Sum / 1KB) + " KB"; $TinyByte }
elseif($Profile_Sum -gt 1048576 -and $Profile_Sum -lt 1073741824){ $MediumByte = " {0:N2}" -f ($Profile_Sum / 1MB) + " MB"; $MediumByte }
elseif($Profile_Sum -gt 1073741824){ $GiganticByte = " {0:N2}" -f ($Profile_Sum / 1GB) + " GB"; $GiganticByte } } Catch {}
$Begin_Time = Get-Item -Path $Global:BackUp_Path | Select-Object -ExpandProperty LastWriteTime
$End_Time = Get-Date -Format G
Get-Job | Remove-Job
[System.Windows.MessageBox]::Show("Copying Complete!`nStart Time: $Begin_Time `nEnd Time: $End_Time `nProfile Size copied: $Size")
}
} | Out-Null
}
" "
Write-Output -InputObject "Copying will be done in background."
Write-Output -InputObject "You will be notified when copying is done."
} catch [System.Management.Automation.Remoting.PSRemotingTransportException]{
"Unable to connect to PC: $Computer `nError: $($Error[0].Exception.Message.Split('.')[2].Trim())!"
}
}
}
}
I removed some information that could get me in trouble but, it's all cosmetics.(:
EDIT: I must be on crack but, everything is working now. Only changes I made was clearing the global variables ($Global:var = $null) before assigning it a value. Thank you all for the suggestions. Another change i made was change Copy-Item to Robocopy instead.
To just answer your question:
Why is my if statement not being read properly?
Just before you evaluate Get-EventSubscriber your are cancelling your event subscription and thus deleting your event subscriber. Get-EventSubscriber therefore returns $null which evaluates to $true, when negated. In conclusion, the code after your if statement will always be executed immediately.
Commented code:
Register-ObjectEvent -InputObject $job -EventName StateChanged -Action {
$eventSubscriber | Unregister-Event # Here you cancel your event subscription
$eventSubscriber.Action | Remove-Job
if (-not (Get-EventSubscriber)) { # Therefore, Get-EventSubscriber returns $null; not $null evaluates to $true
...
The relevant part in the documentation of Unregister-Event:
The Unregister-Event cmdlet cancels an event subscription that was created by using the Register-EngineEvent, Register-ObjectEvent, or Register-WmiEvent cmdlet.
When an event subscription is canceled, the event subscriber is deleted from the session and the subscribed events are no longer added to the event queue. When you cancel a subscription to an event created by using the New-Event cmdlet, the new event is also deleted from the session.

Adding PSCustomObject to Array gives Error, but works fine when debugging the code in Powershell

I know this question is already answered, but that question didn't answered my question.
The link is Adding PSCustomObject to Array gives Error, but works fine when debugging the code in Visual Studio Code
When I am trying to run the script its executing fine in debug mode but its failing if I am executing directly.
$path = Split-Path $script:MyInvocation.MyCommand.Path
$output_File = $path + "\$outputFile_Name"
$report = #()
function Folder-Access
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$prod_path,
[Parameter(Mandatory=$true, Position=1)]
[string]$non_prod_path
)
Write-Host "`$prod_path value: $prod_path"
Write-Host "`$non_prod_path value: $non_prod_path"
try {
$prod_acl = get-acl $prod_path
$nonProd_acl = Get-Acl $non_prod_path
$arr = #()
foreach ($non_prod_usr in ($nonProd_acl.access) ) {
$x = $non_prod_usr.IdentityReference.Value
$arr += $x
}
foreach ($usr in ($prod_acl.Access)){
$dirObj = New-Object psobject
if ($usr.IdentityReference.Value -in $arr) {
echo "Do Nothing."
} else {
if ($usr.IdentityReference.Value -ne 'BUILTIN\Administrators') {
if ($usr.IdentityReference.Value -ne 'S-1-5-21-2554127390-2720852439-1129525235-1959308') {
$properties = [ordered]#{'Foldername'=$non_prod_path; 'AD Group'=$usr.IdentityReference.Value;
'Permissions'=$usr.Filesystemrights}
echo "Do Something."
$usr.IdentityReference.Value
#$dirObj | Add-Member -MemberType NoteProperty -Name "Foldername" -Value $non_prod_path
#$dirObj | Add-Member -MemberType NoteProperty -Name 'AD Group' -Value $usr.IdentityReference.Value
#$dirObj | Add-Member -MemberType NoteProperty -Name 'Permissions' -Value $usr.Filesystemrights
#$report += $dirObj
$report += New-Object -TypeName psobject -Property $properties
}
}
}
#$report += New-Object -TypeName psobject -Property $properties
} $report | Export-Csv -Path 'C:\Powershell\output.csv' -Append -NoTypeInformation -Encoding UTF8
}
catch {
Write-Host "Error occured " + $_ -ForegroundColor Red
}
}
function executionTimeForSourcePath {
try {
$Prod_Folder_Path = Get-ChildItem -Directory -Path $prod_path -Recurse -Force
$Prod_Folder_Path | ForEach-Object {
if (-not ([string]::IsNullOrEmpty($_.FullName))){
$path = $_.FullName
$folderName = $path.Replace($prod_path + '\',"")
if (-Not (Test-Path "$non_prod_path\$folderName")){
try {
New-Item -ItemType Dir -Path "$non_prod_path\$folderName" -ErrorAction Stop
if (Test-Path "$non_prod_path\$folderName"){
Folder-Access -prod_path $path -non_prod_path "$non_prod_path\$folderName"
}
}
catch {
Write-Host $_ -ForegroundColor Red
}
}
ElseIf (Test-Path "$non_prod_path\$folderName") {
Folder-Access -prod_path $path -non_prod_path "$non_prod_path\$folderName"
}
} }
} catch { $_ }
}
echo "Script started.."
executionTimeForSourcePath
Would be great if someone can guide me here please. I tried all the possible ways but none worked for this.
The error is
Method invocation failed because [System.Management.Automation.
PSObject] does not contain a method named 'op_Addition'.

Set idleTimeoutAction from octopus

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.

Powershell export all detailed logging to csv file

I have inherited a script that is not working. I need to capture everything that would normally output to the console, including Success and Error entries from the script. This is only a small portion of the script, and it only captures errors. Any help would be appreciated on getting all output to the file instead of the console.
An example is the Write-Verbose "VERIFYING contact for $($User.WindowsEmailAddress)"
I know this is writing to the console, but I need it to write to the log that is defined at the very bottom of the script.
Catch
{Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);ERROR;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Update;;;Error updating user: $($Error[0])" -FilePath $LogFilePath -Append}
I hope this makes sense.
### UPDATES
ForEach ($User in $colUpdContact)
{
Write-Verbose "VERIFYING contact for $($User.WindowsEmailAddress)"
#Filter used to find the target contact object(s)
$strFilter = "WindowsEmailAddress -eq `"$($User.WindowsEmailAddress)`""
Try
{$colContacts2 = Invoke-Command -Session $targetSession -ScriptBlock {param ($strFilter) Get-Contact -Filter $strFilter} -ArgumentList $strFilter -ErrorAction Stop}
Catch
{Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);ERROR;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Find;;;Error getting contact: $($Error[0])" -FilePath $LogFilePath -Append}
ForEach ($Contact in $colContacts2)
{
#initialize update string and cmd string
$strUpdateContact = $null
$updateCmd = $null
$strWriteBack = $null
$writeBackCmd = $null
#Iterate through attributes and append to the strUpdateContact string if the attribute value has changed
ForEach ($Attrib in $arrAttribs)
{
If ($User.$Attrib -ne $Contact.$Attrib)
{
if($ReadOnly){
Add-Content -Path $readOnlyFilePath -Value " Changing $Attrib"
Add-Content -Path $readOnlyFilePath -Value " Before: $($Contact.$Attrib)"
Add-Content -Path $readOnlyFilePath -Value " After: $($User.$Attrib)"
}
$strUpdateContact += " -$($Attrib) `"$($User.$Attrib)`""
Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);CHANGE;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Update;$($Contact.$Attrib);$($User.$Attrib);" -FilePath $LogFilePath -Append
}
}
#Check if LegacyExchangeDN has been written back to User object
$mailContact = Invoke-Command -Session $targetSession -ScriptBlock {param ($contact) Get-MailContact $($contact.WindowsEmailAddress)} -ArgumentList $Contact -ErrorAction Stop
$x500 = "X500:$($mailContact.LegacyExchangeDN)"
$userRec = Invoke-Command -Session $sourceSession -ScriptBlock {param ($User) Get-Recipient $($User.WindowsEmailAddress)} -ArgumentList $User -ErrorAction Stop
if($UserRec.emailAddresses -notcontains $x500){
$userName = ($user.UserPrincipalName).Split('#')[0]
if($userName -eq "")
{
$userName = $user.SamAccountName
}
$strWriteBack = "Set-ADUser -Identity $userName -Add #{ProxyAddresses=`"$x500`"} -Server $sourceDC -Credential `$sourceDCCredential"
}
#If there is anything to update
If ($strUpdateContact.Length -gt 0)
{
Write-Verbose "Updating attributes for $($User.WindowsEmailAddress)"
#Prepend the command for the contact being modified
$strUpdateContact = "Set-Contact $($User.WindowsEmailAddress) " + $strUpdateContact
If ($ReadOnly)
{Add-Content -Path $readOnlyFilePath -Value $strUpdateContact}
Else
{
Try
{
#Create the complete command and invoke it
$updateCmd = "Invoke-Command -Session `$targetSession -ScriptBlock {$($strUpdateContact)}"
Invoke-Expression $updateCmd -ErrorAction Stop
}
Catch
{Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);ERROR;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Update;;;Error updating contact: $($Error[0])" -FilePath $LogFilePath -Append}
}
}
If ($strWriteBack){
Write-Verbose "Updating X500 for $($User.WindowsEmailAddress)"
Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);CHANGE;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Update;;$x500;" -FilePath $LogFilePath -Append
If($ReadOnly){
Add-Content -Path $readOnlyFilePath -Value $strWriteBack
}
else{
Try
{
Invoke-Expression $strWriteBack -ErrorAction Stop
}
Catch
{Out-File -InputObject "$(Get-Date -Format MM.dd.yyyy-HH:mm:ss);$($WriteMode);ERROR;Target;$($targetUser.Split('#')[1]);$($User.WindowsEmailAddress);Update;;;Error updating user: $($Error[0])" -FilePath $LogFilePath -Append}
}
}
}
}
Why you not use the Start-Transcript to output all the information into a log file, and then you can manually copy anything you want?
An example for the command:
Start-Transcript -Path $TranscriptOutputFile -Append -Force
#Your script; write-output 'something update';
Stop-Transcript
Everything output by write-output command will be appended into the log file.