I have a simple script which is used to delete files from a folder. The script accepts two parameters:
The path of the folder to delete from
A list of items to be excluded from deletion
This is the script I have:
Param(
[Parameter(Mandatory=$True)]
[string]$pathDeleteFrom,
[Parameter(Mandatory=$True)]
[string[]]$excludeFiles
)
Remove-Item -path $pathDeleteFrom -exclude $excludeFiles -Recurse
I'm testing the script in a folder with the following structure:
Example (running the script for path "C:/test/files/*"):
If "*.txt" is excluded, only the .json files are removed.
If I want to delete all files except the folder and it's contents I tried excluding "folder" and "folder/*", however it doesn't seem to work.
What I'm failing to understand is, whether there's a way for me to exclude the "folder" and it's contents using wildcards.
I know that this is probably a simple question but I have tried searching online but failed to find an example similar to the scenario that I have.
This should do what you're trying to accomplish... just fill in the blank and modify the condition statements to what you need.
$items = Get-ChildItem -Path "Directory Path" -Recurse
foreach($item in $items)
{
if($item.name -like "*.TXT" -or $item.name -like "*.Json")
{
#CODE HERE
}
elseif(($item.GetType()).Name-eq "DirectoryInfo" -and $item.name -eq "Directory Name")
{
#CODE HERE
}
}
Related
I've been trying for a while and still haven't got the solution
Can anyone help me with a Powershell script to go over all the folders inside a path and copy all the subfolders with specific name
for example: C:\Clients -is the main folder and under it I have many clients names and subfolders
I would like for each client inside the clients folder to copy the Proposals folder
and so I will have a new C:\Test\Clients*Clientname\Proposal...
what I have so far is:
$Files = #(Get-ChildItem -Path 'C:\tst' -Name)
foreach ($i in $Files){
$names= "C:\tst\$i"
Write-Host $names
Copy-Item -Path $names -Destination "C:\tst2" -Recurse
I'm missing the Filter part
Could you help me again with a powershell script?
I want to check if multiple folders exist, if they exist then delete the complete folder.
Also provide information if the folder has been deleted or information if the folder does not exist.
I now use the script below for multiple files. (thanks to good help)
I want to use the same script for 1 or more folders.
For example, delete folder c:\test1\ and c:test2
Folders may be deleted, even if they still contain files.
$paths = "c:\test\1.txt", "c:\test\2.txt", "c:\test\3.txt"
foreach($filePath in $paths)
{
if (Test-Path $filePath) {
Remove-Item $filePath -verbose
} else {
Write-Host "Path doesn't exits"
}
}
I'm not super handy with powershell, hope you can help me with this again.
Thanks
Tom
To remove a directory (folder) that has content, you must use the -Recurse switch with Remove-Item - otherwise, an interactive confirmation prompt is presented.
A given path existing doesn't necessarily mean that it is a directory - it may be a file. To specifically test if a given path is a directory / file, use -PathType Container / -PathType Leaf with Test-Path.
While only strictly necessary when paths happen to contain [ characters, the robust way to pass literal paths is via the -LiteralPath parameter that file-processing cmdlets support - by contrast, the first positional argument typically binds to the -Path parameter (e.g., Test-Path foo is the same as Test-Path -Path foo), which interprets its argument(s) as wildcard expressions.
Applied to your use case (note that no attempt is made to distinguish files from directories):
# Input directory paths.
$paths = 'c:\test1', 'c:\test2', 'c:\test3'
foreach ($path in $paths) {
if (Test-Path -LiteralPath $path) {
Remove-Item -LiteralPath $path -Verbose -Recurse -WhatIf
} else {
"Path doesn't exist: $path"
}
}
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.
Another, more efficient option is to use Get-Item to get objects representing the file-system items, if they exist, and pipe them to Remove-Item:
$paths = 'c:\test1', 'c:\test2', 'c:\test3'
Get-Item -LiteralPath $paths -ErrorAction SilentlyContinue -ErrorVariable errs |
Remove-Item -Recurse -Verbose -WhatIf
if ($errs) {
"The following path(s) do not exist: $($errs.TargetObject)"
}
Note the use of -ErrorAction SilentlyContinue to silence errors resulting from nonexistent paths, and -ErrorVariable errs in order to collect these errors in self-chosen variable $errs.
The .TargetObject property of the [System.Management.Automation.ErrorRecord] instances collected in $errs then contains the path that triggered the error, resolved to a full path.
This has been sort of asked, but none of the questions I've found have quite answered what I'm looking to do. I'm working with PowerShell (brand new to it) to write a script that will search for subdirectories within a directory and move those to a designated directory if found.
My problem lies within the following code:
$Folders = C:\Users\temp
$MoveFolders = Test-Path $Folders -PathType Container
Write-Host $MoveFolders
#I'm writing this with ISE, so I'm using write-host to view output for testing.
The problem I'm running into is that every time this code is ran, it returns true, even when there are no folders within the temp directory. I've tried it with about every conceivable way I can imagine, and tested with get-childitem piped with a where-object, but I want to only execute the move if a subdirectory is present.
The idea behind it is that, if a user somehow adds a file or folder to this specific one, it will be moved when the task scheduler runs the script.
EDIT
Redirecting my question; It always returns true, and a couple of people have pointed out that what I have written will test the temp folder itself; so is there a way to test for any subfolders and store it as a boolean value, which I can then pass to an if statement that will finish the move process?
I believe this is what you want to do.
#get the folders/subfolders from the directory
$folders = Get-ChildItem C:\Users\temp -Recurse -Directory
#loop through the folders
foreach($folder in $folders) {
#copy the the folder(s) and item(s) within to the destination
Copy-Item -Path $folder.FullName -Destination C:\test -Recurse
}
Here is the updated answer since you edited your question.
$items = Get-ChildItem -Path C:\Users\mkrouse\Desktop\test -Directory -Recurse
#if items is equal to null, then there are no subfolders so assign the boolean to true
if($items -eq $null) {
[bool]$NoSubfolders = $true;
} else {
[bool] $NoSubfolders = $false;
}
Your code tests whether "c:\users\temp" is a folder - which is always true. You need to look for folders within "c:\users\temp". One approach:
$Folders = "C:\temp"
$MoveFolders = Get-ChildItem -Path $folders -Directory
Write-Host $MoveFolders.Count
$MoveFolders now contains a list of all folders within "c:\users\temp". Now you have a list of folders to be moved.
I have a scenario where the powershell script should be deleting the log files and log folders in a path, lets say they are under the path C:\MLA\logs.
Below is the script that I have been using, it completes removes the files but the problem is the script does not work for deleting the folders, the error it displays is something like could not find part of the path
C:\MLA\logs\ART_Daily.
below is the script
$root=C:\MLA\logs
$limit=(Get-Date).AddDays(-90)
get-childitem -Path $root -Recurse -force |
where-Object {(($_.name -match 'Daily|ART|ABC|IIC') -or ($_.PSIsContainer -match 'Daily|ART|ABC|IIC')) -and ($_.CreationTime -lt $limit)} |Remove-Item -recurse -Force
The $name checks for files ( if the names piped are part of the file name for any of the file ) in the root path and $.PSIsContainer check for folders 9 f the names piped are part of the folder name for any of the folder ) inside the root path which is parametrized.
Can you help me out.
You need to correct your filter for starters:
$_.name -match 'Daily|ART|ABC|IIC'
will match files and folders with that name.
$_.PSIsContainer -match 'Daily|ART|ABC|IIC'
Will find nothing because the PSIsContainer property is boolean (is it a container or not: True/False?).
I have two disks which has the same directory structure. C:\Files and D:\Files
Both C:\Files and D:\Files have multiple directories under them but have the same name etc, but the files inside them differ in extension. In C:\Files they are *.csv and in D:\Files, a process monitors the files (copied from C:\) and once it is done changes the files to *.processed.
I want a script that would do that copy. I.e copy files from C:\Files to D:\Files which have not been processed by comparing only the file names.
You want something like this. The property you want to compare on is called BaseName which powershell helpfully adds for you to the IO.FileSystemInfo class (FileInfo.BaseName exists in PowerShell but not in straight .NET). BaseName is just the name of the file, and doesn't contain any of the extensions that you don't care about.
$sourceFiles = Get-ChildItem C:\files -Recurse -File -Filter "*.csv"
$destinationFiles = Get-ChildItem D:\files -Recurse -File
foreach($sourceFile in $sourceFiles) {
$exists = $destinationFiles | Where-Object {$_.BaseName -eq $sourceFile.BaseName}
if(!$exists) {
Copy-Item $sourceFile.fullname -Destination "D:\Files\$($sourceFile.BaseName)"
}
}
dir .\ *csv -Recurse -File | cp -ea Ignore -WhatIf -Destination {
$dest=$_.FullName-replace'^C:','D:'-replace'\.csv','.processed'
if(Test-Path $dest){
Write-Host Already exists -ForegroundColor Yellow
$null
}else{
Write-Host Copying... -ForegroundColor Green
$dest-replace'\.processed$','.csv'
}
}
Notice the WhatIf parameter: you must remove it, if you're going to really copy the items.
Also, you may like to remove the 2 lines withwrite-host cmdlet.
Notive too, that I have hard-coded the C: and D: drives as source and destine drives.