Try Catch Query Powershell - powershell

Can anyone advise why when I run this script I still get a generic error generated by powershell? It is nested in an IF statement originally.
try {
Remove-Item -Path "C:\Users$env:USERNAME\AppData\Local\Microsoft\Outlook" -Force -Recurse | Out-Null
} catch { "Appdata Cache does not exist!"
}

catch only works on terminating errors. So you’ll have to change your try statement to. Also you’re missing a “\” in your path
Try{
Remove-Item C:\Users\$env:USERNAME\AppData\Local\Microsoft\Outlook" -Force -Recurse -ErrorAction Stop
}Catch{
“Appdata cache doesn’t exist”
}
Also Remove-Item doesn’t return an object so you don’t need to redirect it to null

Related

Directory creation failure and no errors

I made a function and I thought it worked well. In my primary script I am importing the function and then calling it. The idea of the function is simply to make a filename with a path.
At the end of the function I added a portion that would check if the directory exists and if not create it.
Here are the problems.
I get no errors.
The directory is not always created`.
When the primary script runs and attempts to export the csv it doesn't because the directory doesn't exist.
3a) if I create the directory everything works.
The folder it tries to create is "C:\Reports" but I am an admin on the computer and I understand it should be in special folders. I suppose I can force that if you folks want. But I would think I would get an error if the directory could not create as written below.
Portion of the function that should be working.
$ProcessError = $null
IF (!(test-path $DirectoryName)) {
New-Item -Path $DirectoryName -ItemType Directory -ErrorAction SilentlyContinue -ErrorVariable ProcessError -Force
If ($ProcessError) {
Write-Warning "Problem trying to create $DirectoryName."
}
Return [string]$FullPath
}
This is the primary call to the function and what is strange is I get no error here as well in section 2 primary below!!
section 1 primary
If ($SimChange -eq $True) {
$ResultFileName = MRNAP -ReportName "ExampleGoogleLicenseReport" -Move -JustDate
}
Else {
$ResultFileName = MRNAP -ReportName "GoogleLicenseReport" -Move -JustDate
}
Section 2 primary
$ProcessError = $null
$Results | Export-Csv $ResultFileName -NoTypeInformation -ErrorVariable ProcessError -ErrorAction SilentlyContinue
If ($ProcessError) {
Write-Warning "Unable to save report output to $ResultFileName"
}
url to function that creates the filename.
https://github.com/dcazman/MRNAP/blob/main/MRNAP.ps1
I find this all very frustrating and Section 2 primary above. Should be giving me that warning as written....I thought.
In the comments there is chat about a bug and using try catch. Additionally, we have talked about this problem on stack before with
Create directory if it does not exist
and
Function return value in PowerShell
What I did for now that works.
IF (!(test-path $DirectoryName)) {
$Dircreate = New-Item -ItemType Directory -Force -Path $($DirectoryName.Substring(0, 3)) -Name $($DirectoryName.Substring(3)) -ErrorAction SilentlyContinue -ErrorVariable ProcessError | Out-Null
If ($ProcessError) {
Write-Warning "Problem trying to create $DirectoryName."
[bool]$Created = $False
}
Else {
[bool]$Created = $true
}
}
If ($Created) {
If ($FullPath -as [string]) {
Return [string]$FullPath
}
Else {
Return [string]$FullPath[1]
}
}
This above doesn't use a try catch but I will give that a shot later.
For some bug reason creating the directory was changing $fullpath from a string to an array and that is why the test above works using the -as [string]

Handle Directory Exists Exception

I am new to PowerShell. I have a piece of code which checks whether a folder "ilalog" exists or not. When I run this script first time, it is checking for the folder "ilalog",if it does not exist,it is creating. When I run the script second time. I receive the error below:
An item with the specified name D:\Temp\ilalog already exists
"FullyQualifiedErrorId :
DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand".
how to handle this exception
I have tried using try and Catch block
$rgflder="ilalog"
[bool]$checkrg=Test-Path D:\Gdump\$rgfolder -PathType Any
if ( $checkrg -eq $False)
{
try{
New-Item -Path "D:\Gdump" -Name "$rgflder" -ItemType "directory"
}
catch [System.IO.IOException]
{
if ($_.CategoryInfo.Category -eq $resExistErr) {Write-host "Dir Exist"}
}
}
else
{
Write-Output "Directory Exists"
}
If you want to continue processing your script while taking action based on an error type, a simple way is to just examine the $error variable. Using Trap may be an option as well.
$error.clear()
New-Item -Path "D:\Gdump" -Name "$rgflder" -ItemType "directory"
if ($error[0].Exception.GetType().Fullname -eq 'System.IO.IOException') {
"Dir Exists"
}
else {
"Dir was created"
}
If you want to use try-catch, you need to treat your non-terminating error as a terminating error to activate the catch block. You can do this with -ErrorAction Stop.
try {
New-Item -Path "D:\Gdump" -Name "$rgflder" -ItemType "directory" -ErrorAction Stop
}
catch [System.IO.IOException]
{
"Exception caught!"
}
Alternatively, you can manage this within your session by setting $ErrorActionPreference = 'Stop', which will apply to all commands within that session.
Keep in mind that the value passed to -ErrorAction overrides the setting in $ErrorActionPreference. Also, error action settings have no affect on terminating errors. So you cannot expect to set -ErrorAction Continue and have code continue processing on a terminating error.
Many commands return objects that may or may not be terminating errors. You will find more success explicitly, specifying when you want to throw a terminating error.
You can read more about error action preference at About Common Parameters. I actually like Everything About Exceptions for exception handling in PowerShell.
Why not simply do like below?
$rgflder="ilalog"
# combine the path and foldername
$rgPath = Join-Path -Path 'D:\Gdump' -ChildPath $rgflder
# test if the folder already exists
if (Test-Path $rgPath -PathType Container) {
Write-Output "Directory Exists"
}
else {
# if not, create the new folder
try {
$null = New-Item -Path $rgPath -ItemType Directory -ErrorAction Stop
Write-Output "Created directory '$rgPath'"
}
catch {
# something terrible happened..
Write-Error "Error creating folder '$rgPath': $($_.Exception.Message)"
}
}

Bug copying item with Literalpath or intended?

Consider the following really simple code:
Try {
Copy-Item -Path '\\server\g$\thisfolder\thisfiledoesntexist.ini' -Destination 'c:\temp' -ErrorAction Stop
}
Catch {
"Ran into an issue: $_"
}
This will work fine to trap the error for a non-existent souce file. However the following will not - there's no error generated.
Try {
Copy-Item -LiteralPath '\\?\UNC\server\g$\thisfolder\thisfiledoesntexist.ini' -Destination 'c:\temp' -ErrorAction Stop
}
Catch {
"Ran into an issue: $_"
}
However...this WILL trap the error
Try {
Get-ChildItem -LiteralPath '\\?\UNC\server\g$\thisfolder\thisfiledoesntexist.ini' -ErrorAction Stop | Copy-Item
}
Catch {
"Ran into an issue: $_"
}
This is the first time I've had occasion to use Literal paths - is this behaviour intended/expected?
I think you've found a bug with Copy-Item under Windows PowerShell. It seems including a ? character anywhere in input for either -Path or -LiteralPath stops an error from being trapped for a non-existent path.
The bug seems to have been fixed on PowerShell Core, where your code above does result in an exception being caused.

Powershell. Write event logs

I have a script which moves some files from a folder to the temp folder, archives them and cleans the temp folder at the end.
I want my script to also write information about it in the win-event log.
Here is my script:
Get-ChildItem C:\Users\Administrator\Desktop\test1\ | Where-Object {$_.LastWriteTime -lt "09/24/2018 09:00 PM"} | Move-Item -Destination C:\Users\Administrator\Desktop\data\
Compress-Archive -path C:\Users\Administrator\Desktop\data\ -CompressionLevel Optimal -DestinationPath C:\Users\Administrator\Desktop\data1\test.zip
Remove-Item C:\Users\Administrator\Desktop\data\*
I want to add code which will write an event for any error into the win-event log.
Per the comments, you can use Write-EventLog to write to the Windows Event Logs. If you want to write any errors that occur during those commands, then you probably want to use a Try..Catch to catch any errors and handle them:
Try {
$PrevEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
Get-ChildItem C:\Users\Administrator\Desktop\test1\ | Where-Object {$_.LastWriteTime -lt "09/24/2018 09:00 PM"} | Move-Item -Destination C:\Users\Administrator\Desktop\data\
Compress-Archive -path C:\Users\Administrator\Desktop\data\ -CompressionLevel Optimal -DestinationPath C:\Users\Administrator\Desktop\data1\test.zip
Remove-Item C:\Users\Administrator\Desktop\data\*
Catch {
Write-Error $_
$ErrorEvent = #{
LogName = 'Application'
Source = 'YourScript'
EventID = 123
EntryType = 'Information'
Message = $_
}
Write-EventLog #ErrorEvent
}
Finally {
$ErrorActionPreference = $PrevEAP
}
In order for an exception (error) to trigger a Try..Catch the exception needs to be terminating (vs non-terminating). You can force cmdlets to do terminating errors by setting the cmdlets -ErrorAction to Stop, or you can do this globally via the $ErrorActionPreference variable.
In the catch block, the error is held in the special variable: $_. So we can use Write-Error to still write it out to the console (if you want to) and then we're using Write-EventLog to write it into the Event Log.
Customise LogName, Source, EventID, Information etc. as per your needs. Note LogName needs to be one of the existing Logs and Entry Type needs to be one of the valid entry types (Information, Warning, Error).

PowerShell module terminating unexpectedly

A PowerShell module I'm working on is behaving very strangely...
I have the following code in a RestoreTestFiles.psm1 file (located in %USERPROFILE%\My Documents\WindowsPowerShell\Modules\RestoreTestFiles\):
Function Restore-TestFiles([string]$backupDir, [string]$destinationDir, [bool]$overwrite)
{
if (!(Test-Path $backupDir))
{
Write-Host "Error, $backupDir does not exist."
return
}
if ($backupDir.EndsWith("\*"))
{
Write-Host "$backupDir ends with \*!"
}
else
{
Write-Host "$backupDir does not end with \*."
}
if ($overwrite)
{
Copy-Item -Path $backupDir -Destination $destinationDir -Recurse -Force
}
else
{
Copy-Item -Path $backupDir -Destination $destinationDir -Recurse
}
Write-Host "Files sucessfully copied from $backupDir to $destinationDir."
}
And I call the function like this:
Import-Module RestoreTestFiles
Restore-TestFiles "C:\some\path\*" "C:\someOther\path\"
For some reason, the output is only either
C:\some\path\* ends with \*!
or
C:\some\path does not end with \*.
But it never runs the Copy-Item or the final Write-Host. If I set a breakpoint, the execution is all messed up:
Stops at breakpoint set on if (!(Test-Path $backupDir))
I step into and it goes to if ($backupDir.EndsWith("\*"))
I step into and it goes to Write-Host "$backupDir ends with \*!"
I step into and it stops running.
Why is the script terminating before it is supposed to?
Edit: I tried moving the function to a regular .ps1 script and called the function from the same script and it works fine...it only terminates prematurely if the function is in a module and called from outside the module. What gives?
I was able to fix this by completely closing all open instances of the PowerShell ISE and re-opening my module.