PowerShell: List all items except for certain files - powershell

Get-childItem | Where-Object { ($_.CreationTime).ToString('dd/MM/yyyy') -EQ 01/01/2017}
How do you create exceptions when listing files ? So if I want to list every file in a directory apart from files called "File 1" and "File 2"

Using the -Exclude parameter on Get-ChildItem:
Get-ChildItem -Exclude File1,File2 | Where-Object { ($_.CreationTime).ToString('dd/MM/yyyy') -EQ 01/01/2017}

Get-childItem | Where-Object {$_.Name -ne 'file 1' -and $_.name -ne 'file 2'}

Either of the above examples will work, it's more of a preference. I personally like to do as much filtering of the data before I pass it along the pipeline.

Related

Get a list of all specific empty subfolders inside employee's folders

Could you please help me with a directory operation?
I have an employee directory and in that directory, there are about 200+ employees subdirectories named by their employee code. And within each employee's subdirectory, there are about 20 subfolders referring to various documents. For example, subfolder named 'Educational Documents'. This 'Educational Documents' subfolder exists in each of these 200+ employee's folders.
I want to output a text or csv file listing all such 'Educational Documents' subfolders out of those 200+ employees which are empty or in other words where scanned PDF files have not been copied as yet. By doing so, I will be able to use that output file as a task list for myself to populate all those empty folders by putting scanned PDF documents for the missing employee data.
I have tried to use DOS commands with /S switch but that does not precisely cater to my needs and therefore I am looking at some Powershell script which could get this done.
My code so far:
$Search = gci -Filter "Educational Documents" -Recurse -Path "D:\Employees" -Directory
Foreach ($path in $Search.fullname)
{
Write-Output $path | Out-File d:\Filelist.txt -append
$file = gci -path $path | select name
$file.name | Out-File d:\filelist.txt -append
Write-Output "------- Next Folder --------------" | Out-File d:\Filelist.txt -append
}
If I understand correctly, you want a file listing of all empty folders called 'Educational Documents'.
To do that, you could make use of the GetFileSystemInfos() method of the DirectoryInfo objects returned by Get-ChildItem like this:
$Search = Get-ChildItem -Path "D:\Employees" -Filter "Educational Documents" -Recurse -Directory |
Where-Object { $_.GetFileSystemInfos().Count -eq 0 } | Select-Object -ExpandProperty FullName
# add '-PassThru' to also output this list on screen
$Search | Set-Content -Path 'D:\Empty_EducationalDocuments_Folders.txt'
Hope that helps
As per your comment, you would like to list both empty folders and folders that do not have a file with the word Graduation in their name, you can edit the above to become
$Search = Get-ChildItem -Path "D:\Employees" -Filter "Educational Documents" -Recurse -Directory |
Where-Object { $_.GetFileSystemInfos().Count -eq 0 -or
$_.GetFiles("*Graduation*", "TopDirectoryOnly").Count -eq 0 } |
Select-Object -ExpandProperty FullName
# add '-PassThru' to also output this list on screen
$Search | Set-Content -Path 'D:\EducationalDocuments_Folders_without_Graduation_File.txt'
You can try this code:
$Search = Get-ChildItem -Recurse -Path "D:\Employees" -Directory
foreach ($path in $Search.fullname)
{
$directoryInfo = Get-ChildItem -Path $path | Measure-Object
if($directoryInfo.count -eq 0)
{
$path | Out-File "D:\Filelist.txt" -append
Write-Output "------- Next Folder --------------" | Out-File "D:\Filelist.txt" -append
}
}
I used some code from this question: Test if folder is empty

Deleting bulk files with the same extension while preserving files with the same extension

Get-ChildItem "I:\TEMP_Dir_SSN\" | %{
if($_.name -ne "fullpath.txt" -or $_.name -ne "SSN_FILES.txt"){
remove-item $_.fullname
}
}
There are two files in the same directory that I don't want to delete. I want to delete all but two .txt files. They need to be preserved in the same directory. However, the rest is garbage and can be removed.
You can utilize Where-Object in your pipeline to accomplish what you're trying to do.
Get-ChildItem "I:\TEMP_Dir_SSN\" |
Where-Object { (($_.Name -notlike 'fullpath.txt') -and
($_.Name -notlike 'SSN_FILES.txt')) } |
Remove-Item
Just a note for more terse reading/writing, you can use the built-in alias GCI and Where
I would use the Exclude parameter to exclude the files:
Get-ChildItem "I:\TEMP_Dir_SSN" -Exclude "fullpath.txt","SSN_FILES.txt" | Remove-Item

Compare-Object Delete File if file does not exist on source

I have this PowerShell code that compares 2 directories and removes files if the files no longer exist in the source directory.
For example say I have Folder 1 & Folder 2. I want to compare Folder 1 with Folder 2, If a file doesn't exist anymore in Folder 1 it will remove it from Folder 2.
this code works ok but I have a problem where it also picks up file differences on the date/time. I only want it to pick up a difference if the file doesn't exist anymore in Folder 1.
Compare-Object $source $destination -Property Name -PassThru | Where-Object {$_.SideIndicator -eq "=>"} | % {
if(-not $_.FullName.PSIsContainer) {
UPDATE-LOG "File: $($_.FullName) has been removed from source"
Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
}
}
Is there an extra Where-Object {$file1 <> $file2} or something like that.?
I am not sure how you are getting the information for $source and $destination I am assuming you are using Get-ChildItem
What i would do to eliminate the issue with date/time would be to not capture it in these variables. For Example:
$source = Get-ChildItem C:\temp\Folder1 -Recurse | select -ExpandProperty FullName
$destination = Get-ChildItem C:\temp\Folder2 -Recurse | select -ExpandProperty FullName
By doing this you only get the FullName Property for each object that is a child item not the date/time.
You would need to change some of the script after doing this for it to still work.
If I am not getting it wrong, the issue is your code is deleting the file with different time-stamp as compared to source:
Did you try -ExcludeProperty?
$source = Get-ChildItem "E:\New folder" -Recurse | select -ExcludeProperty Date
The following script can serve your purpose
$Item1=Get-ChildItem 'SourcePath'
$Item2=Get-ChildItem 'DestinationPath'
$DifferenceItem=Compare-Object $Item1 $Item2
$ItemToBeDeleted=$DifferenceItem | where {$_.SideIndicator -eq "=>" }
foreach ($item in $ItemToBeDeleted)
{
$FullPath=$item.InputObject.FullName
Remove-Item $FullPath -Force
}
Try something like this
In PowerShell V5:
$yourdir1="c:\temp"
$yourdir2="c:\temp2"
$filesnamedir1=(gci $yourdir1 -file).Name
gci $yourdir2 -file | where Name -notin $filesnamedir1| remove-item
In old PowerShell:
$yourdir1="c:\temp"
$yourdir2="c:\temp2"
$filesnamedir1=(gci $yourdir1 | where {$_.psiscontainer -eq $false}).Name
gci $yourdir2 | where {$_.psiscontainer -eq $false -and $_.Name -notin $filesnamedir1} | remove-item
If you want to compare files in multiple dir, use the -recurse option for every gci command.

Powershell: Exclude numerous folders with -notmatch statement

I'm creating a small script which will list EXE files on the computer.
$computername = get-content env:computername
get-childitem C: -recurse | ? {$_.fullname -notmatch 'C:\\Windows'} | where {$_.extension -eq ".exe"} | format-table fullname | Out-File "\\server\incomming\$computername.txt"
The problem is that -notmatch doesn't accept more statements. I could copy-paste ? {$_.fullname -notmatch 'C:\\Windows'} and use for other folders like Program Files (x86), Program Files and so on. But I wouldn't like to bloat a script too much.
Is there a way I could exclude numerous folders with -notmatch statement?
You can use the logical operators like -and for more complex logical expressions.
Get-ChildItem C:\ -Recurse | Where-Object { ($_.FullName -notmatch "C:\\Windows") -and ($_.FullName -notmatch "C:\\Program Files") }
For many paths, I'd add them to an array or a hash table before calling Get-ChildItem and use Where-Object check if the pipeline file object path is present in the array or hash table. Eventually, you have to list the paths somewhere, but not necessarily in a single command. For example:
$excludedPaths = #("C:\Windows", "C:\Program Files");
Get-ChildItem C:\ -Recurse | Where-Object { $excludedPaths -notcontains $_.Directory }
Thanks for the answers!
And is it possible to get output longer than it is now?
It is now something like 100 symbols and then it ends with dots if path is longer than that.
I've get something like this -
C:\my files\my programs\prog...
I would use something like this:
get-childitem -literalpath e:\*.exe -Recurse | where { $_.DirectoryName -notmatch "Windows" -and $_.DirectoryName -notmatch "MyOtherFiles"}

File extension while searching

I am trying to get a list of all my files with a specific extension.
(...)$_.Extension -eq ".$ext"
I read extension from console to script.
My question is how to find any file with an extension of .*?
Edit:
Here's the rest of the code:
$setOfFolders = (Get-ChildItem -Path D:\ -Directory).name
Write-host "Set last write date " -ForegroundColor Yellow -NoNewline
$ostZmiana= read-host $exten = read-host "Set extensions "
ForEach ($f in $setOfFolders)
{
$saveTofile = "C:\Users\pziolkowski\Desktop\Outs\$f.txt"
Get-ChildItem -Path D:\Urzad\Wspolny\$f -Recurse | ? {$_.LastAccessTime -lt $ostZmiana -and $_.Extension -eq ".$exten"} | % {Get-acl $_.FullName} |sort Owner | ft -AutoSize -Wrap Owner, #{Label="ShortPath"; Expression= $_.Path.Substring(38)}} > $saveToFile
}
You can also use the -filter on Get-ChildItem:
Get-ChildItem -Filter "*.txt"
And you can specifiy recursion too:
Get-ChildItem -Recurse -Filter "*.txt"
The $_.Extension will see the file as, (in the case of a text file) .txt
If $ext is currently a valid extension, then .$ext would look like ..txt echoed out.
The easiest way to get a list of files with a specific extension in PowerShell is one of two, really.
C like syntax:
$myList
Get-ChildItem |`
Foreach-Object {
if ($_.Extension -eq ".txt") { $myList += $_}
}
PowerShell style:
Get-ChildItem | Where-Object {$_.Extension -eq ".txt"} | Do stuff
To get all files, as most files have an extension, just use Get-ChildItem or GCI or ls. (GCI and LS are aliases for Get-ChildItem).
To get all files with an extension, but not a specific extension:
Get-ChildItem | Where-Object {$_.Extension}
This evaluates as a bool, so true or false.
These are off the cuff, but should get you going in the right direction.