Powershell Remove-Item Cmdlet error - powershell

I'm using powershell to remove a directory with the command:
Remove-Item $pathAsString -Recurse -Force
However, it gives me the following error:
Remove-Item : Cannot remove the item at 'C:\Path' because it is in use.
At line:1 char:1
+ Remove-Item "C:\Path" -Recurse
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Remove-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RemoveItemCommand
I thought that was odd, because the directory shouldn't be in use. I can go into file explorer and delete the directory manually. I'm not really sure why this behavior is occurring. I'm fairly new to powershell, so don't understand exactly how it behaves.
My scripts interaction with the program includes:
Creating the folder
Downloading an MSI to the folder
Setting a variable to represent the MSI stored in the folder. Like so:
$MSIVariable = Get-ChildItem $Path | Where {&_.Name -eq "MSIName.msi"}
I'm assuming that something to do with the folder is within a stream of some sort, but don't know how I'd fix this issue.
EDIT:
Here is the code I use involving the folder:
Creating the Folder:
if(!(Test-Path $MSILocation))
{
New-Item $MSILocation -ItemType directory
}
Downloading the MSI:
$webClient = (New-Object System.Net.WebClient)
$downloadLocation = Join-Path $MSILocation $MSIName
$webClient.DownloadFile($downloadURL, $downloadLocation)

Related

Can't remove Windows fonts using this powershell script

I'm totally noob in powershell scripting. Trying to remove some fonts that are installed on the system. I saved the fonts in the following folder "C:\Temp\fonts\fonts-to-be-installed". The script should find the font name in that folder and remove the matching fonts from registry and C:\Windows\Fonts folder. However, when I run this script it doesn't work. I don't get any error messages. Wondering whats's missing here. Any hints would be appreciated.
# Remove fonts
$Fontstoberemoved = Get-ChildItem -Path "C:\Temp\fonts\fonts-to-be-installed\" | Where-Object Name -Like "*.ttf"
foreach ($font in $Fontstoberemoved) {
Write-Output "Deleting item: 'C:\Windows\Fonts\$font.Name'"
Remove-Item -Path "C:\Windows\Fonts\$font.Name" -Force
Write-Output "Deleting item: 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\$font.Name'"
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" -Name $font.Name -Force
}
I've just modified the script to remove the fonts from one more location as below:
**Remove-Item -Path "$env:LOCALAPPDATA\Microsoft\Windows\Fonts\$font" -Force**
Now I'm getting the following error message:
"Remove-Item : Cannot find path 'C:\Users\xxxx\AppData\Local\Microsoft\Windows\Fonts\Linotype - NHaasGroteskTXPro-56It.ttf' because it does not exist. At line:4 char:1
+ Remove-Item -Path "$env:LOCALAPPDATA\Microsoft\Windows\Fonts\$font" - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\xxxx...kTXPro-56It.ttf:String) [Remove-Item], ItemNotFoundEx ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand"
The fonts are still in that folder. When I try to manually delete the fonts I get a warning message that the file is open in system. Wondering how to detect which process is using the fonts?

Test-Path returns True but ExtractToDirectory Could not find path

I have a simple powershell script which is supposed to ease some deployment tasks.
In an earlier portion of the script, I create a virtual drive mapped to Z: which is on a remote server. The part that is tripping up is when it tries to unzip the files on the remote server mapped to Z:
function UnzipBuild($destinationFolder)
{
Add-Type -assembly "System.IO.Compression.Filesystem"
$zipFiles = Get-ChildItem -Path $destinationFolder -Filter *.zip
foreach($zip in $zipFiles)
{
$folderName = $zip.ToString().TrimEnd(".zip")
$extractPath = Join-Path $destinationFolder $folderName
New-Item -ItemType Directory $extractPath
Write-Host "Extracting $zip to $extractPath `r`n"
[io.compression.zipfile]::ExtractToDirectory([string]$zip.FullName, "$extractPath")
}
}
When it reaches the ::ExtractToDirectory line it throws an exception
Hit Line breakpoint on 'D:\MyDeploymentScript.ps1:85'
[DBG]: PS C:\WINDOWS\system32>>
Exception calling "ExtractToDirectory" with "2" argument(s): "Could not find a part of the path
'Z:\Build_11_17_13_28\Web'."
At D:\MyDeploymentScript.ps1:85 char:9
+ [io.compression.zipfile]::ExtractToDirectory([string]$zip.FullName, "$ex ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DirectoryNotFoundException
But the crazy thing is if I breakpoint that same spot and check the path with Test-Path it returns True. I am at a loss for what can be wrong right now.
[DBG]: PS C:\WINDOWS\system32>> Test-Path Z:\Build_11_17_13_28\Web
True
It seems like you might be mapping your drive in the earlier portion of the script with New-PSDrive. The drive created with that cmdlet is only visible within PowerShell, unless you use the -Persist switch. That switch creates it as an actual mapped drive (as though you had used net use or group policy or mapped it through explorer).
The .ExtractToDirectory method you're calling can't see any of the powershell provider namespaces, so it needs a real mapped drive or UNC path that's visible to the whole operating system.
Remember that if you're using -Persist you may also want to unmap the drive manually now.

Access is denied - confusion over COPY-ITEM

I am trying to copy some files from my server to a workstation. If I change $Foldername to C:\the process works fine. However if I leave the code the way it is, i.e. If I decide to copy files to C:\Program Files\Interrogator.
I get this error:
Copy-Item : Access to the path 'C:\Program Files\Interrogator\Setup Instructions.txt' is denied.
At C:\Users\coduy\Desktop\Copy2Test.ps1:20 char:10
+ Copy-Item <<<< -Path \\10.10.0.10\DeploymentShare\Applications\JDE-Interrogator\* -Destination $Foldername
+ CategoryInfo : PermissionDenied: (\\10.10.0.10\De...nstructions.txt:FileInfo) [Copy-Item], Unauthorized
AccessException
+ FullyQualifiedErrorId : CopyFileInfoItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.CopyItemCommand
I can see that the access is denied but why? I have not shared any of the folders and that should not make any difference if I decide to copy to C:\ or C:\Program Files
$net = New-Object -comobject Wscript.Network
$net.MapNetworkDrive("Z:","\\10.13.0.10\DeploymentShare\Applications\JDE Interrogator",0,"mydomain\coduy","P0kroy$")
$uncServer = "\\10.10.0.10\"
$uncFullPath = "\\10.13.0.10\DeploymentShare\Applications\JDE Interrogator"
$username = "coduy"
$password = "password"
$Foldername="C:\Program Files\Interrogator"
net use $uncServer $password /USER:$username
try
{
mkdir C:\'Program Files'\Interrogator
Copy-Item -Path \\10.10.0.10\DeploymentShare\Applications\JDE-Interrogator\* -Destination $Foldername
}
finally {
net use $uncServer /delete
}
Found out that other user has similar issue and this seems to be a reasonable answer:
Windows Vista and above default to not allowing non-administrative
users to write to the `%PROGRAMFILES% folder. This means that you're
not going to be allowed to copy the files there; you're also not going
to be able to save them after doing your find/replace operation.
You can write them to your user documents folder
(%USERPROFILE%\Documents) folder instead, if that will work for you.
share|edit answered Dec 23 '12 at 6:32
Ken White
74.5k770140

How to pipe a directory name into Remove-Item?

I'm not very savvy with powershell, so any help is appreciated.
I have a drive that holds users profiles. I need to remove a specific file from each user's profile. It's structured something like this. (Names changed to protect the innocent.)
E:\Profiles
UserID
Documents
OtherFolders
DirectoryToDeleteFrom
FileToDelete.txt
UserID2
...
...
I could use the following command to delete all of the files I need to get to, but it's unbearably slow as it's recursing through all of the other folders under UserID.
#this one would work perfectly, but is terribly slow
Get-ChildItem -Path E:\Profiles -Include FileToDelete.txt -Recurse
I know exactly where each file resides, so I thought that I could do this.
(Get-ChildItem -Path 'E:\Profiles' -Exclude *.lnk)|ForEach-Object{Remove-item -path 'E:\Profiles\' + $_.Name + '\Path\To\File\FileToDelete.txt'}
But I get the following error message:
Remove-Item : A positional parameter cannot be found that accepts
argument '+'. At line:1 char:70
+ (Get-ChildItem -Path 'E:\Profiles' -Exclude *.lnk)|ForEach-Object{Remove-item ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Remove-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
I thought it was because I was passing Remove-Item a bad file path, but the following command generates the correct paths.
(Get-ChildItem -Path 'E:\Profiles' -Exclude *.lnk)|ForEach-Object{'E:\Profiles\' + $_.Name + '\Path\To\File\FileToDelete.txt'}
So what am I doing wrong here?
If you construct a string on the fly to be used inline, by another command, then put brackets around the path:
..{Remove-item -path ('E:\Profiles\' + $_.Name + '\Path\To\File\FileToDelete.txt')}

Delete broken link

I need to delete all the content of a folder which may include broken links among others. The folder path is provided by a variable. Problem is that PowerShell fails to remove the broken links.
$folderPath = "C:\folder\"
Attempt 1:
Remove-Item -Force -Recurse -Path $folderPath
Fails with error:
Remove-Item : Could not find a part of the path 'C:\folder\brokenLink'.
At line:1 char:1
+ Remove-Item -Force -Recurse -Path $folderPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\folder\brokenLink:String) [Remove-Item], DirectoryNot
FoundException
+ FullyQualifiedErrorId : RemoveItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Attempt 2:
Start-Job { cmd /c rmdir $folderPath }
Fails because $folderPath gets passed as is instead of its value:
Start-Job { cmd /c rmdir $folderPath } | select command
Command
-------
cmd /c rmdir $folderPath
Any suggestion besides using the .NET framework?
EDIT
By broken link I'm referring to a folder which points to a previously mounted partition, that doesn't exist anymore. The folder is still available but when attempting to navigate into it this error occurs because the destination doesn't exist anymore:
Error:
C:\folder\brokenLink refers to a location that is unavailable. It
could be on a hard drive on this computer, or on a network. Check to
make sure that the disk is properly inserted, or that you are
connected to the Internet or your network, and then try again. If it
still cannot be located, the information might have been moved to a
different location.
This will work:
$folderPath = "C:\folderContaingBrokenSymlinks\";
$items = ls $folderPath -Recurse -ea 0;
foreach($item in $items){
if($item.Attributes.ToString().contains("ReparsePoint")){
cmd /c rmdir $item.PSPath.replace("Microsoft.PowerShell.Core\FileSystem::","");
}
else{
rm -Force -Recurse $item;
}
}