Get Count of a Zip folder + match size Powershell - powershell

Trying to get Count of a zip folder that has for example 30 CSV files
The test folder has 30 csv files
$directoryInfo = Get-ChildItem "$TEST\*.csv" | Measure-Object
$directoryInfo.count
All 30 csv files will be compressed into a zip folder = TESTZIP1.zip located inside of TEST folder.
If I try to run the following to measure how many files are inside of the compressed folder, I get 0 as answer
$backUP = Get-ChildItem "$zipfiletest\TESTZIP1.zip\*.csv" | Measure-Object
$backUP.count
Goal: able to Count() how many files are inside of zip folder, and if zip folder has the same amount of files as TEST folder, sends an email.

If you want to count the files inside your zip-file, you can do it like this:
$ZipFile = [System.IO.Compression.ZipFile]::Open("$zipfiletest\TESTZIP1.zip",[System.IO.Compression.ZipArchiveMode]::Read)
$ZipFile.Entries.count
$ZipFile.Dispose()
If you want to check anything else inside the zip file, you can easily explore the other parameters of the $ZipFile variable

$fileToCheck = Get-Item -Path (Join-Path -Path "C:\Users\" -ChildPath test.zip) - ErrorAction SilentlyContinue
$ZipFiles = Get-ChildItem -Path $fileToCheck -Recurse -Filter '*.zip'
$Shell = New-Object -ComObject Shell.Application
$Results = foreach( $fileToCheck in $ZipFiles ){
$DATCount = $Shell.NameSpace($fileToCheck.FullName).Items() |
Where-Object { $_.Name -match '\.dat$' } |
Measure-Object |
Select-Object -ExpandProperty count

Related

Merge CSV files in subfolders

I have found a script which does everything that I need, but it's only useful if you run it in a single folder. What I'd like is:
Script is located in c:/temp/. Upon running the script, it would go into each subfolder and execute. Each subfolder would then have a separate Final.csv.
Somebody mentioned just add -Recurse, but it doesn't complete the job as described. With -Recurse added, it goes into each subfolder and creates a Final.csv final in the root dir (C:/temp/) instead of creating a Final.csv in each subfolder.
$getFirstLine = $true
get-childItem *.csv | foreach {
$filePath = $_
$lines = Get-Content $filePath
$linesToWrite = switch($getFirstLine) {
$true {$lines}
$false {$lines | Select -Skip 2}
}
$getFirstLine = $false
Add-Content Final.csv $linesToWrite
}
If you are certain the csv files combined this way will leave you a valid 'Final.csv', you need to use Group-Object in order to create a combined file in each of the directories where the csv files to combine are found.
Suppose you have a folder with subfolders 'Folder1' and 'Folder2', both having csv files in them like these:
first.csv
Lorem,Ipsum,Dolor,Sic,Amet
data1-1,data1-2,data1-3,data1-4,data1-5
data2-1,data2-2,data2-3,data2-4,data2-5
second.csv
Lorem,Ipsum,Dolor,Sic,Amet
something,blah,whatever,very important,here's more..
Then this should do it for you:
$targetFileName = 'Final.csv'
# loop over the CSV files, but exclude the Final.csv file
# Group the files by their DirectoryNames
Get-ChildItem -Path 'D:\Test' -Filter '*.csv' -File -Recurse -Exclude $targetFileName | Group-Object DirectoryName | ForEach-Object {
# reset the $getFirstLine variable for each group
$getFirstLine = $true
# create the target path for the combined csv inside this folder.
# ($_.Name is the name of the group, which is the Directory name of the files inside the group)
$target = Join-Path -Path $_.Name -ChildPath $targetFileName
foreach ($file in $_.Group) {
if ($getFirstLine) {
# copy the first CSV as a whole
Get-Content -Path $file.FullName | Set-Content -Path $target
$getFirstLine = $false
}
else {
# add the content of the next file(s) without the header line
Get-Content -Path $file.FullName | Select-Object -Skip 1 | Add-Content -Path $target
}
}
}
The end result is that each subfolder will have a new 'Final.csv' file containing
Lorem,Ipsum,Dolor,Sic,Amet
data1-1,data1-2,data1-3,data1-4,data1-5
data2-1,data2-2,data2-3,data2-4,data2-5
something,blah,whatever,very important,here's more..
Of course I'm just showing an example for one of the subfolders.. Other subfolders will contain different 'Final.csv' content

PowerShell Get video duration and list all files recursively, export to csv

I want to get a csv listing of all the video files (MTS or MP4 format) in a folder and its subfolders. I need the name with path, file size, and video duration.
I had used this PowerShell script to successfully get a list of all the files from the main folder and subfolders. But this script does not get the video file metadata from which I can extract the duration.
Get-ChildItem D:\'My Source Folder' -Recurse | where {!$_.PSIsContainer} | select-object FullName, LastWriteTime, Length | export-csv -notypeinformation -path C:\results_file.csv | % {$_.Replace('"','')}
I'm completely new to PowerShell scripting, so I'm unable to figure out how to get the videofile metadata.
Note: I'm aware select-object * gets all the attributes of the file, but unfortunately that too does not have the duration which is specific to video files only.
I also found this answer, but I need a listing of all files in all subfolders, exported to a csv.
This code should help
$Directory = "D:\My Source Folder"
$Shell = New-Object -ComObject Shell.Application
Get-ChildItem -Path $Directory -Recurse -Force | ForEach {
$Folder = $Shell.Namespace($_.DirectoryName)
$File = $Folder.ParseName($_.Name)
$Duration = $Folder.GetDetailsOf($File, 27)
[PSCustomObject]#{
Name = $_.Name
Size = "$([int]($_.length / 1mb)) MB"
Duration = $Duration
}
} | Export-Csv -Path "./temp.csv" -NoTypeInformation

powershell Script for unzipping in specific named folder

I have several zip files which have generated names like 21321421-12315-sad3fse-23434fg-ggfsd which doesn't help to identify the content of the zip.
I need a script, which unzips it and then looks for a pdf file with a partly-generated & static name eg asdawd-ersrfse-231-Formular2311.
After that it should create a folder with the name of the pdf file and unzip all zip-file content into this folder.
So far I only have to snippets that work after each other, but I'm still stuck.
$shell = new-object -com shell.application
$CurrentLocation = get-location
$CurrentPath = $CurrentLocation.path
$Location = $shell.namespace($CurrentPath)
# Find all the Zip files and Count them
$ZipFiles = get-childitem -Path "C:\Install\NB\Teststart" *.zip
$ZipFiles.count | out-default
# Set the Index for unique folders
$Index = 1
# For every zip file in the folder
foreach ($ZipFile in $ZipFiles) {
# Get the full path to the zip file
$ZipFile.fullname | out-default
# Set the location and create a new folder to unzip the files into - Edit the line below to change the location to save files to
$NewLocation = "C:\Install\NB\Testfinal\$Index"
New-Item $NewLocation -type Directory
# Move the zip file to the new folder so that you know which was the original file (can be changed to Copy-Item if needed)
Copy-Item $ZipFile.fullname $NewLocation
# List up all of the zip files in the new folder
$NewZipFile = get-childitem $NewLocation *.zip
# Get the COMObjects required for the unzip process
$NewLocation = $shell.namespace($NewLocation)
$ZipFolder = $shell.namespace($NewZipFile.fullname)
# Copy the files to the new Folder
$NewLocation.copyhere($ZipFolder.items())
# Increase the Index to ensure that unique folders are made
$Index = $Index + 1
}
Get-ChildItem -Path "C:\Install\NB\Testfinal" -Include "*.pdf" -Recurse | ForEach-Object {
$oldFolder = $_.DirectoryName
# New Folder Name is .pdf Filename, excluding extension
$newFolder = $_.Name.Substring(0, $_.Name.Length - 4)
# Verify Not Already Same Name
Write-Host "Rename: $oldFolder To: $newFolder"
Rename-Item -NewName $newFolder -Path $oldFolder
}
Along the same lines as your own script, firstly extract the zips and then rename the extracted folder to the same as the pdf:
$SourceDir = 'C:\Install\NB\Teststart'
$ExtractDir = 'C:\Install\NB\Testfinal'
# Extract each zip to a folder with the same name as the zip file (BaseName)
Get-ChildItem (Join-Path $SourceDir *.zip) | foreach {
Expand-Archive $_.FullName -DestinationPath (Join-Path $ExtractDir $_.BaseName)
}
# Rename the PDF's parent folder to the same as the PDF
Get-ChildItem (Join-Path $ExtractDir *.pdf) -Recurse | foreach {
Rename-Item -Path $_.Directory.FullName -NewName $_.BaseName
}
This should do and it's much simpler than what you have. It relies on .NET 4.5 which you should have on your server already:
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
# Get all the zip files in the root of the script, change $PSScriptRoot accordingly
Get-ChildItem -Path $PSScriptRoot -Filter *.zip -Recurse | ForEach-Object {
# Open the archive for reading
$zip = [IO.Compression.ZipFile]::OpenRead($_.FullName)
# Find the name of the PD file from the archive entries
$archiveName = $zip.Entries | `
Where-Object { [System.IO.Path]::GetExtension($_.FullName) -eq '.pdf' } | `
Select-Object #{N = "BaseName"; E = {[System.IO.Path]::GetFileNameWithoutExtension($_.FullName)}} |
Select-Object -Expand BaseName
# Close the zip file
$zip.Dispose()
# Use the native Expand-Archive to unzip the archive
# Ammand $PSScriptRoot to the destination base path if needed
Expand-Archive -Path $_.FullName -DestinationPath (Join-Path $PSScriptRoot $archiveName)
}

PowerShell move most recent file from each folder

I need some assistance with powershell - I would like to search within all subfolders of a particular folder, and copy the latest file from each subfolder to a new folder every day at 9.00 AM. So, I want to search within folder A's subfolder a, b and c to pick out the latest file in a, b and c each, and move all three files into outside folder B (a single folder). I am new to PowerShell - any help is appreciated. I've basically tried to use this but it creates a backup: Copy most recent file from folder to destination
Clear-Host
$ChildFolders = #('In_a', 'In_b', 'In_c')
for($i = 0; $i -lt $ChildFolders.Count; $i++){
$FolderPath = "C:\FolderA\" + $ChildFolders[$i]
$DestinationPath = "C:\FolderB\" [$i]
gci -Path $FolderPath -File | Sort-Object -Property LastWriteTime -Descending | Select FullName -First 1 | %($_){
$_.FullName
Copy-Item $_.FullName -Destination $DestinationPath
}
Gets subfolders
Gets all files in subfolders
Sorts files by Creation Date into a array
Gets first Entry
Moves file to Destination directory
*It will overwrite files with the same name in the destination folder
Function Get-LatestFiles($SourceFolder,$Destination){
$Subfolders = Get-ChildItem $SourceFolder -Directory
[System.Collections.ArrayList]$SubFoldersExpanded = new-object System.Collections.ArrayList
Foreach($SubFolder in $SubFolders){
$SubFolderExpanded = $Subfolder | %{(Get-ChildItem $_.FullName -File -Depth 1 | Sort-Object -Property CreationTime -Descending)}
if($SubFolderExpanded.Count -gt 0){
$SubFolderExpanded[0] | %{Move-Item $_.FullName -Destination $Destination -force}
}
}
}
Get-LatestFiles -SourceFolder C:\test -Destination C:\test01

Powershell file copy and rename based on path

I have folder Main that has many subfolders (AA,AB,AC,...,ZZ), every subfolder has 5 folders (1,2,3,4,5) in which one them can have .csv file.
I need a to write a script that would copy every .csv file into output folder and rename it based on in which subfolder it was found (AA.csv, BB.csv and so on) all I managed to do was get a list of csv files and create output folder.
New-Item C:\Output -force
$FileExtension = ".csv"
$Dir = get-childitem $FolderPath -recurse
$List = $Dir | where {$_.extension -eq $FileExtension}
$List | format-table Name
I suppose you can have multiple csv files into your dirs, i propose this solution
$Pathsource="C:\Temp\" # let the '\'
$Pathdestination="C:\Temp2\"
#remove -whatif if its ok
Get-ChildItem $Pathsource -Recurse -Filter "*.csv" | %{Copy-Item $_.FullName ($Pathdestination + $_.FullName.Replace($Pathsource , '').Replace('\', '_')) -WhatIf}