Unsere erneute Ernennung als Citrix Platinum Partner von der Cloud Software Group ist mehr als…
Excel Bulkupdate with password protection and locked cells
Hey there,
a customer decommissioned his 2003 Server and migrated his files to a new server running a current version of Windows
The issue:
– 1000’s of excel files
– The excel files contain server paths which are referencing to each other
– Some files are password protected
– different passwords used
– locked cells
As there is nothing out there, we decided to write up a script: Use at your own risk!
This script scans a directory for files containing the extension „.xls“ or „.xlsm“ and tries a list of passwords.
Excel must be installed on the system running the script.
It has been written for a german version of excel, so you may need to edit the part #Exceptionhandling in the later section of the script to your regional settings
##parameter section# #################### $folder = "D:\fileshare\data" $oldname = "\\oldserver\fileshare" $newname = "\\newserver\fileshare" #Passwords #keep "no password" and "errorpassword" as it is used by the script! $arrPasswords = @("no password","secretpassword","verysecret","ultrasecret","errorpassword") #reporting $ScriptReportFolder = "C:\scripts\report\" $ScriptReport =@() ############ ## Main #### ############ $object = New-Object -comObject Shell.Application #get excel files $excelfiles = Get-ChildItem $folder -Recurse | where {($_.Extension -eq ".xls") -or ($_.Extension -eq ".xlsm")} if (!$folder -or !$oldname -or !$newname) {exit} #Excel COM Object $excel = New-Object -comObject Excel.Application $excel.Visible = $false $excel.DisplayAlerts = $false $progressI = 0 #loop through results foreach ($file in $excelfiles) { Write-Host "--------------------------" Write-Host "Datei:" $file.Fullname #Prepare Report set $Report = "" | Select "File", "Result", "Date" $Report.File = $file.FullName $Report.Date = Get-Date #start password cracker Write-Host "Start password cracker" foreach ($password in $arrPasswords){ #open file with excel trying all known passwords try { Write-Host "password: $password" $workbook = $excel.Workbooks.Open($file.FullName,0,0,5,"$password") if ($workbook.Name -ne ""){ Write-Host "Workbook is opened sucessfull" Write-Host "Starting foreach Sheet" #set indicator for modified data $modifieddata = $false } #replace links foreach ($sheet in $workbook.Sheets) { Write-Host "##Sheet:" $sheet.Name #get used cells $objRange = $sheet.UsedRange #check if pattern was found if ($objRange.Find($oldname)){ #set indicator for modified data $modifieddata = $true #check if there is protected content if ($sheet.ProtectContents -eq "True"){ Write-Host "Protected Cells found!" #save current protection $sheetprotectcontents = $sheet.ProtectContents $sheetprotectdrawingobjects = $sheet.ProtectDrawingObjects #unprotect sheet Write-Host "Unprotect Sheet" $sheet.Unprotect() #here we need to check each cell one by one $i = 0 while ($cell = $objRange.Find($oldname)){ Write-Host "Column:" $cell.column "Row:" $cell.row #save current locked status $cellprotected = $cell.Locked if ($cellprotected -eq $true){ $cell.Locked = $false } $cell.Replace($oldname, $newname) if ($cellprotected -eq $true){ $cell.Locked = $true } $i++ if ($i -eq 999) { Write-Host "maximum retries reached"; break } }#end while cell findings #protect the sheet again Write-Host "Protecting Sheet again" $sheet.Protect($null,$sheetprotectcontents, $sheetprotectdrawingobjects) } else { #Use the replace function Write-Host "Replacing Data by Search&Replace Function" $objRange.Replace($oldname, $newname) } } else { Write-Verbose "pattern not found" }#end if pattern found }#end foreach sheet #work is finished, save and close the document if ($modifieddata -eq $true){ Write-Host "Save file" $workbook.Save() $Report.Result = "Success" }else { Write-Host "skipped, pattern not found" $Report.Result = "skipped, pattern not found" } Write-Host "close file" $workbook.Close() #password worked, exit foreach break } catch { #Exceptionhandling #error not related to the password if (($($Error[0].Exception.Message)) -notlike "*Das eingegebene Kennwort ist ungültig*"){ $Report.Result = "Failed with error $($Error[0].Exception.Message)" break } #error, all passwords have been tried, non worked out if (($password -eq "errorpassword") -and ($($Error[0].Exception.Message)) -like "*Das eingegebene Kennwort ist ungültig*"){ $Report.Result = "Unknown Password" break } continue } }#end password cracker #send results to report array $ScriptReport += $Report #update progressbar $progressI++ Write-Progress -activity "Updating Files...." -Status "Scanned: $progressI of $($excelfiles.count)" -percentComplete (($progressI / $excelfiles.count) * 100) }#end excel file $excel.quit() #save the report $ScriptReport | ConvertTo-Csv -Delimiter ";" -NoTypeInformation | Out-File -FilePath (Join-Path "$ScriptReportFolder" "$(Get-Date -Format yyyMMddHHmm)excelupdate.csv") [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers()
Dieser Beitrag hat 0 Kommentare