'Clipboard access denied, csv to xlsx conversion
I have a most peculiar issue with clipboard. Below is the code I've written that in essence gathers info about many many thousands of files, compares hashes, compares filnames and lists zero length files and then writes them all to an xlsx file in separate worksheets.
Everything works fine if the scope is relatively small (i.e. ~20k files), but if the scope becomes greater (i.e. ~200k files) I get an error Clipboard access denied. Initially I believed that the issue was clipboard capacity, as I use clipboard and .pastespecial method. But when intermediate csv files are created and their contents copied, everything seems to work fine. Ant thoughts?
Original script
$excel = New-Object -com excel.application
$excel.SheetsInNewWorkbook = 2
$excel.displayalerts = $false
$workbook = $excel.workbooks.add()
$worksheet = $workbook.worksheets
$True_Dups = $worksheet.item(1)
$True_Dups.name = "True Duplicates"
$Dupes = $worksheet.item(2)
$Dupes.name = "Name Duplicates"
$wbPersonalXLSB = $excel.workbooks.open("$env:USERPROFILE\Application Data\Microsoft\Excel\XLSTART\PERSONAL_2.XLSB")
$path = "PATH"
$GCI = GCI $path -file -Recurse -Ea 0
$hashes =
$GCI|
Get-FileHash -Algorithm MD5 -Ea 0|
select Algorithm, Hash, @{l="File";e={$_.Path.split("\")|select -Last 1}},@{l="Path";e={$_.Path.Substring(0,$_.Path.LastIndexof('\'))}}, @{l="Link";e={$_.Path}}|
Group -property "Hash"|
Where {$_.Count -ge 2}|
select -Expand Group
$hashes|ConvertTo-Csv -NoTypeInformation -Delimiter "`t"|scb
$True_Dups.Cells.Item(1).pastespecial()|out-null
$True_Dups.activate()
$excel.run("PERSONAL_2.XLSB!Empty_Row_Dupes")
$filenames =
$GCI|
Select @{l='File';e={$_.PSChildName}}, @{l='Compare Filename';e={$_.BaseName.replace('_','*').replace(' ','*').replace('-','*')}}, Directory, FullName, @{l="Extension";e={$_.Extension}}|
group -Property 'Compare Filename'|
Where {@($_.Group.Extension |Sort -Unique).Count -ge 2}|
select -expand Group
$filenames|ConvertTo-Csv -NoTypeInformation -Delimiter "`t"|scb
$Dupes.Cells.Item(1).pastespecial()|out-null
$Dupes.Activate()
$excel.run("PERSONAL_2.XLSB!Empty_Row_Dupes")
$wbPersonalXLSB.Close()
$Empty = $worksheet.add([System.Reflection.Missing]::Value,$worksheet.Item($worksheet.count))
$Empty.Name = "Zero Lenght"
$zero_length =
$GCI|
? {$_.Length -eq 0}|
Select @{l='File';e={$_.PSChildName}}, Length, Directory, FullName
$zero_length|ConvertTo-Csv -NoTypeInformation -Delimiter "`t"|scb
$zero_length.cells.item(1).pastespecial()|out-null
$zero_length.range("A1:D1").Interior.Color = 8454080
$save = "CSV_PATH"
$workbook.saveas($save)
$workbook.close()
$excel.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)|out-null
Remove-Variable excel
Interdemiate CSVs added
$start = Get-Date
$path = "Path"
$GCI = GCI $path -file -Recurse -Ea 0
$hashes =
$GCI|
Get-FileHash -Algorithm MD5 -Ea 0|
select Algorithm, Hash, @{l="File";e={$_.Path.split("\")|select -Last 1}},@{l="Path";e={$_.Path.Substring(0,$_.Path.LastIndexof('\'))}}, @{l="Link";e={$_.Path}}|
Group -property "Hash"|
Where {$_.Count -ge 2}|
select -Expand Group
$hashes|export-Csv "PATH_1 csv" -NoTypeInformation
$filenames =
$GCI|
Select @{l='File';e={$_.PSChildName}}, @{l='Compare Filename';e={$_.BaseName.replace('_','*').replace(' ','*').replace('-','*')}}, Directory, FullName, @{l="Extension";e={$_.Extension}}|
group -Property 'Compare Filename'|
Where {@($_.Group.Extension |Sort -Unique).Count -ge 2}|
select -expand Group
$filenames|export-Csv "PATH_2.csv" -NoTypeInformation
$zero_length =
$GCI|
? {$_.Length -eq 0}|
Select @{l='File';e={$_.PSChildName}}, Length, Directory, FullName
$zero_length|export-Csv "PATH_3.csv" -NoTypeInformation
$span = ((get-date) - $start).ToString("hh\:mm\:ss")
Write "Span lasted $span"
and conversion script (credit goes to the original creator linked at the end)
$path = "CSV_FOLDER"
$csvs = Get-ChildItem $path -filter *.csv
$y = $csvs.Count
Write-Host "Detected the following CSV files: ($y)"
Write-Host " "$csvs.Name"`n"
$outputfilename = "Final Registry Results"
Write-Host Creating: $outputfilename
$excelapp = New-Object -ComObject Excel.Application
$excelapp.SheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
for($i=1;$i -le $y;$i++) {
$worksheet = $xlsx.Worksheets.Item($i)
$worksheet.Name = $csvs[$i-1].Name
$file = (Import-Csv $csvs[$i-1].FullName)
$file | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Clip
$worksheet.Cells.Item(1).PasteSpecial()|out-null
}
$output = "XLSX_OUTPUT"
$xlsx.SaveAs($output)
$excelapp.Quit()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
