Essentially I want all the information I can produce below to be in the same variable. Currently I have it in 2 pieces. I would like to get the output from the Split-Path as a new column titled "folder" in the $newdata variable.
$newdata = gci -r C:\temp\Screenshots\*.* |
? {$_.LastWriteTime -gt '12/30/16'} |
% {Get-ItemProperty $_} |
select BaseName, Directory
$newdata | select Directory | % {
Split-Path (Split-Path "$_" -Parent) -Leaf
}
That's what calculated properties are for.
$newdata = Get-ChildItem -Recurse C:\temp\Screenshots\*.* |
Where-Object {$_.LastWriteTime -gt '12/30/16'} |
ForEach-Object {Get-ItemProperty $_} |
Select-Object BaseName, Directory,
#{n='Folder';e={Split-Path $_.Directory -Parent | Split-Path -Leaf}}
Related
I want to copy a file to multiple destinations using a script that filters through a directory and selects the newest file in the $File_path then change its name and copies it to the $destination, the script i'm using is this:
$File_path = "C:\TEMP\export\liste\Text_Utf8\"
$destination = "C:\TEMP\export\C7E001"
get-childitem -path $File_path -Filter "Ges?*.txt" |
where-object { -not $_.PSIsContainer } |
sort-object -Property $_.CreationTime |
select-object -last 1 | copy-item -Destination (join-path $destination "FRER3000CCFETES01_IN.DEV")
this only copies it to one location, is there a way to improve it to copy the same file to multiple locations? i have seen this thread but it seems different.
the other locations are as follow:
C:\TEMP\export\C7P001
C:\TEMP\export\C7F001
C:\TEMP\export\C7S001
and so on.
thank you.
Although my answer isn't very different to Peter's answer, This uses the LastWriteTime property to get the latest file and uses the FullName property of the file to copy in the Copy-Item cmdlet.
$File_path = "C:\TEMP\export\liste\Text_Utf8"
$destinations = "C:\TEMP\export\C7E001", "C:\TEMP\export\C7F001", "C:\TEMP\export\C7S001"
$fileToCopy = Get-ChildItem -Path $File_path -Filter "Ges*.txt" -File |
Sort-Object -Property $_.LastWriteTime |
Select-Object -Last 1
foreach ($dest in $destinations) {
Copy-Item -Path $fileToCopy.FullName -Destination (Join-Path -Path $dest -ChildPath "FRER3000CCFETES01_IN.DEV")
}
You can use an foreach object loop
$File_path = "C:\TEMP\export\liste\Text_Utf8\"
$destination = "C:\TEMP\export\C7E001", "C:\TEMP\export\C7P001", "C:\TEMP\export\C7F001", "C:\TEMP\export\C7S001"
$Files = get-childitem -path $File_path -Filter "Ges?*.txt" |
where-object { -not $_.PSIsContainer } |
sort-object -Property $_.CreationTime |
select-object -last 1
$Destination | Foreach-Object {copy-item $Files -Destination (join-path $_ "FRER3000CCFETES01_IN.DEV")}
my original path is D:\FTP\testftp\clientname\Folder\EDW
where under EDW there are files
i am trying to fetch the latest file and oldest file with file count but in output i want client name also but i am getting name of folder
can any one help how to get the client name in output
here is my script
Get-ChildItem -Path 'D:\FTP\testftp\*\EDW' -Recurse -Directory |
Select Name,FullName,
#{Name='Latestfile';Expression = {(Get-ChildItem -Path $_.FullName -Filter *-SALES.csv | Where {$_.lastWriteTime} | select -last 1).Name}},
#{Name='LastestFileTime';Expression = {(Get-ChildItem -Path $_.FullName -Filter *-SALES.csv| Where {$_.lastWriteTime} | select -last 1).lastWriteTime}},
#{Name='OldestFile';Expression = {(Get-ChildItem -Path $_.FullName *-SALES.csv | Where {$_.lastWriteTime} | select -first 1).Name}},
#{Name='OldestFileTime';Expression = {(Get-ChildItem -Path $_.FullName *-SALES.csv | Where {$_.lastWriteTime} | select -first 1).lastWriteTime}},
#{Name='count';Expression = {(Get-ChildItem -Path $_.FullName -File -Recurse| Measure-Object).Count}}
and its output
Name : EDW
FullName : D:\FTP\testftp\clientname\folder\EDW
Latestfile : HIST-SALES.CSV
LastestFileTime : 11/20/2015 11:08:59 AM
OldestFile : -SALES.CSV
OldestFileTime : 11/21/2025 4:08:49 AM
count : 173
You can create another calculated property to include the client name. We can derive that folder from the FullName by splitting the path into parts by the \.
Get-ChildItem -Path 'D:\FTP\testftp\*\EDW' -Recurse -Directory |
Select Name,FullName,
#{Name='Latestfile';Expression = {(Get-ChildItem -Path $_.FullName -Filter *-SALES.csv | Where {$_.lastWriteTime} | select -last 1).Name}},
#{Name='LastestFileTime';Expression = {(Get-ChildItem -Path $_.FullName -Filter *-SALES.csv| Where {$_.lastWriteTime} | select -last 1).lastWriteTime}},
#{Name='OldestFile';Expression = {(Get-ChildItem -Path $_.FullName *-SALES.csv | Where {$_.lastWriteTime} | select -first 1).Name}},
#{Name='OldestFileTime';Expression = {(Get-ChildItem -Path $_.FullName *-SALES.csv | Where {$_.lastWriteTime} | select -first 1).lastWriteTime}},
#{Name='count';Expression = {(Get-ChildItem -Path $_.FullName -File -Recurse| Measure-Object).Count}},
#{Name='Client';Expression={($_.FullName -split '\\')[3]}}
In $FilesInContainer2 the exclude function is not working as expected.
I need the list of files from $files which is not in $FilesInContainer1
$srcdir = "W:\XXX\"
$zipFilepath = "W:\YYY"
$currentFileExtension = ".txt"
$logFileName = "W:\Log.txt"
$files = Get-ChildItem $srcdir -Filter *.txt | ? {$_.LastWriteTime -ge (Get-
Date).Date} | Sort-Object -Property Name -Descending
$Container1FileCount = [math]::Ceiling(($files).count/2)
$FilesInContainer1 = $files | Select-Object -First $Container1FileCount
$FilesInContainer2 = Get-ChildItem $files -Exclude $FilesInContainer1
Below code will write the list of files from $files which is not in $FilesInContainer1
$FilesInContainer2 = $files | ?{$FilesInContainer1 -notcontains $_}
Why would you do a Get-ChildItem twice at all?
To split the collection of files obtained with the first Get-ChildItem cmdlet, you can simply split that in two by doing something like this:
$srcdir = 'W:\XXX'
$files = Get-ChildItem -Path $srcdir -Filter '*.txt' -File |
Where-Object {$_.LastWriteTime -ge (Get-Date).Date} |
Sort-Object -Property Name -Descending
$half = [math]::Ceiling(($files.Count / 2))
# get the first half of the files colection
$FilesInContainer1 = $files | Select-Object -First $half
# or use $FilesInContainer1 = $files[(0..($half - 1))]
# get the rest (second half) of the files collection
$FilesInContainer2 = $files | Select-Object -Last ($files.Count - $half)
# or use $FilesInContainer2 = $files[($half..($files.Count - 1))]
Hello to the whole community, I am trying to inspect directories and subdirectories of a folder and if one of them gets more than one file if it has more than 15 days to delete it and leave only the most updated.
but I still do not get the way that if I get a single file despite having more than 15 days old do not touch it as long as there is one more updated within the same directory.
I am currently working with this code
$timeLimit = (Get-Date).AddDays(-15)
Get-ChildItem D:\backup\OldFilesTemp -Directory | where LastWriteTime -lt $timeLimit | Remove-Item -Force -Recurse
grateful for the support they can give me.
You could try something like the following:
$timeLimit = (Get-Date).AddDays(-15)
Get-ChildItem D:\backup\OldFilesTemp | Where-Object { $_.PSIsContainer } | ForEach-Object { Get-ChildItem $_ | Where-Object { -not $PSIsContainer } | Sort-Object -Property LastWriteTime -Descending | Select-Object -Skip 1 | Where-Object { $_.LastWriteTime -lt $timeLimit } | Remove-Item -Force }
Replace Remove-Item -Force with Remove-Item -WhatIf to perform a dry run.
$timeLimit = ([System.DateTime]::Today).AddDays(-15) #Dont use Get-Date.
$BackupFolder = "D:\backup\OldFilesTemp"
$FolderList = Get-ChildItem $BackupFolder -Directory -Recurse | Select FullName
Foreach ($Folder in $FolderList)
{
$FileList = Get-ChildItem $Folder -File | Sort-Object -Property LastWriteTime -Descending
$Count = ($FileList | Where-Object -Property LastWriteTime -GE $timeLimit).Count
#Keep an old file if there is only 1 or no recent backups
if ($Count -le 1)
{
$FileList | Where-Object -Property LastWriteTime -LT $timeLimit | Select-Object -Skip 1 | Remove-Item -Force
}
else
{
$FileList | Where-Object -Property LastWriteTime -LT $timeLimit | Remove-Item -Force
}
}
Better do your testing before you deploy on your environment.
I am trying to create a CSV file for a file share that has deep folder structure.
I want the CSV to look like:
filename, filepath, file type, folderStructure
So far I have the following:
#Get-ChildItem -Path D:\ -Recurse
$directory="d:\"
gci $directory -recurse |
where {$_.psiscontainer} |
foreach {
get-childitem $_.fullname |
sort creationtime |
select -expand fullname -last 1
}
You don't need to recurse a recursive in Powershell. It will automatically go through all of the subdirectories of subdirectories.
I am also a little unsure of some of the information you wanted, but here is a script that does what you want mostly I believe and is IMO a little better to read.
Get-ChildItem -Path X:\Test -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$Folder = $_.PSIsContainer
$Age = $_.CreationTime
$Path | Select-Object `
#{n="Name";e={$Item}},`
#{n="Created";e={$Age}},`
#{n="filePath";e={$Path}},`
#{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv X:\Test\Results.csv -NoTypeInformation
You will need to change your path, as I created this for a test. My results look like this in Excel:
+-------------------------------+----------------+-------------------------------------+-----------+
| Name | Created | filePath | Extension |
+-------------------------------+----------------+-------------------------------------+-----------+
| test2 | 3/6/2013 19:21 | X:\Test\test2 | Folder |
| Results.csv | 3/6/2013 19:51 | X:\Test\Results.csv | .csv |
| test3 | 3/6/2013 19:21 | X:\Test\test2\test3 | Folder |
| New Text Document.txt | 3/6/2013 19:21 | X:\Test\test2\New Text Document.txt | .txt |
+-------------------------------+----------------+-------------------------------------+-----------+
Where it says "Folder" for the Extension just it returning that it is a directory instead of a blank (No extension).
OK, I changed the way it checks for the parent. It is no longer looking directly at the Parent attribute, and it should correct it now.
Get-ChildItem -Path D:\ -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[#($ParentS.Length - 2)]
$Folder = $_.PSIsContainer
$Age = $_.CreationTime
$Path | Select-Object `
#{n="Name";e={$Item}},`
#{n="Created";e={$Age}},`
#{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
#{n="filePath";e={$Path}},`
#{n="Extension";e={if($Folder){"Folder"}else{$Type}}}`
}| Export-Csv X:\Test\ResultsC.csv -NoTypeInformation
It is now taking the path to the current item, turning it into an array by splitting on the \, and then giving you the value at ArryLength - 2
I am not sure if this is the best approach but it works. I have a feeling code could be shorten to get the full path of a file.
$myDirectory = "D:\"
Get-ChildItem -Path $myDirectory -Recurse |`
foreach{
$Item = $_
$Type = $_.Extension
$Path = $_.FullName
$ParentS = ($_.Fullname).split("\")
$Parent = $ParentS[#($ParentS.Length - 2)]
$ParentPath = $_.PSParentPath
$ParentPathSplit = ($_.PSParentPath).split("::")
$ParentPathFinal = $ParentPathSplit[#($ParentPathSplit.Length -1)]
#$ParentPath = [io.path]::GetDirectoryName($myDirectory)
$Folder = $_.PSIsContainer
$Age = $_.CreationTime
$Path | Select-Object `
#{n="Name";e={$Item}},`
#{n="Created";e={$Age}},`
#{n="Folder Name";e={if($Parent){$Parent}else{$Parent}}},`
#{n="filePath";e={$Path}},`
#{n="Extension";e={if($Folder){"Folder"}else{$Type}}},`
#{n="Folder Name 2";e={if($Parent){$Parent}else{$Parent}}},`
##{n="Folder Path";e={$ParentPath}},`
#{n="Folder Path 2";e={$ParentPathFinal}}`
}| Export-Csv d:\ResultsC_2_F.csv -NoTypeInformation