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.
Related
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
I am new on powershell and I have an issue. I am trying to make a script that cleans all my directories older than 30 days, but when I run it, it breaks. Does anyone know what problem I have?
$fromNDays = $args[0]
$cutOffDate = (Get-Date).AddDays(-$fromNDays)
$directoriesToDelete = Get-ChildItem -Path $path -Attributes Directory -Filter r* | Where-Object LastWriteTime -le $cutOffDate
echo "deleting from $cutOffDate"
cd $(Agent.ReleaseDirectory)
cd ..\..
pwd
Foreach($directoryToDelete in $directoriesToDelete)
{
if($directoryToDelete.Name -ne "ReleaseRootMapping")
{
try
{
echo "Deleting directory $directoryToDelete"
Remove-Item –path $directoryToDelete.FullName -Force -Recurse
}
catch
{
echo "Failed deleting $directoryToDelete.FullName"
}
}
}
The error that I have when it runs is:
echo "Failed deleting $directoryToDelete.FullName"
+ ~
2020-03-09T09:55:23.3827859Z ##[error]The string is missing the terminator: ".
deleteReleaseDirectoryFrom30.ps1:12 char:5
2020-03-09T09:55:23.3832466Z ##[error]+ {
2020-03-09T09:55:23.3836221Z ##[error]Missing closing '}' in statement block or type definition.
This error apears on line 12, 23, 8 and 10
In your code, the script doesn't know, that $directoryToDelete.FullName is a variable.
So first, put them one into brackets:
try{
echo "Deleting directory ${directoryToDelete}"
Remove-Item –path ${directoryToDelete.FullName} -Force -Recurse
}
catch
{
echo "Failed deleting ${directoryToDelete.FullName}"
}
As described here : https://github.com/PowerShell/vscode-powershell/issues/1308, there is this problem with PS and VSCode.
According to the answers on GitHub, a solution is to paste your code in the Powershell ISE (you can do a simple Windows search for that), and save using it. Then you can continue coding with VsCode or anything else you use.
Hope this helps you, even though I'm a bit late here...
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)"
}
}
As of Windows 10 PowerShell is finally capable of creating Junctions and links natively.
Howerver the Remove-Item function seems to be unaware of the junction and tries to remove the directory asking for confirmation and if it should recursively delete items within.
So, the question is:
Is there a way to remove a junction using PowerShell native Cmdlets? (i.e. without calling cmd)
Is there a way to remove a junction using PowerShell?
Currently, at least in PowerShell v5, this is considered "fixed". What you can do is use the -Force switch, else you will get an error calling the path an NTFS junction. The reason that I at least use the quotes on fixed is that using the switch will still make the message about children in the directory show up. Selecting Y will still only delete the junction in my testing using PSv5.
Remove-Item "C:\temp\junction" -Force -Confirm:$False
If that doesn't work for you or you don't have v5 you can use the .Net method to delete a directory. This appears to work correctly as well.
[io.directory]::Delete("C:\temp\junction")
have a try on this "command-let":
cmd /c rmdir .\Target
source:Powershell Remove-Item and symbolic links
Simple command -
rm [path of file] -Force
After search by Google for a long time, I found the answer:
function Remove-Any-File-Force ($Target) {
if ( Test-Path -Path "$Target" ){
& $env:SystemRoot\System32\ATTRIB.exe -S -H -R "$Target" >$null 2>$null
} else {
return
}
$TargetAttributes = (Get-Item -Path $Target -Force).Attributes.ToString()
if ($TargetAttributes -match "ReparsePoint") {
if ($TargetAttributes -match "Archive") {
Remove-Item -Path "$Target" -Force
} else {
try {
& $env:SystemRoot\System32\cmd.exe /c rmdir /Q "$Target" >$null 2>$null
} catch {
try {
[io.directory]::Delete("$Target")
} catch {
Remove-Item -Path "$Target" -Force
}
}
}
} else {
if ($TargetAttributes -match "Directory") {
Remove-Item -Path "$Target" -Force -Recurse
} else {
Remove-Item -Path "$Target" -Force
}
}
}
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.