How to rename multiple pdfs in Powershell using itextsharp - powershell

Im trying to rename every pdf file in a folder according to variables obtained from those files but i cant get it to work, i can rename one file at a time but i cant manage to make it work for every file.
Here is what i have to rename one file:
Add-Type -Path "C:\Program Files\...\itextsharp.dll"
$file = "C:\Program Files\...\pdf file.pdf"
$pdf = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $file
$text=[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdf,1)
$startss = $text.LastIndexOf("Completo")
$endss = $text.LastIndexOf("Doc")
$name = $text.Substring($startss +9,$endss - $startss-10)
$startss2 = $text.LastIndexOf("Modalidad")
$endss2 = $text.LastIndexOf("(Entre")
$mode = $text.Substring($startss2 +10,$endss2 - $startss2-10)
Rename-Item -NewName ($name + "-" + $mode + ".pdf") -Path "$file"
$pdf.Close()
And here is what i have to rename every file:
$folder = "C:\...\pdfs folder"
Add-Type -Path "C:\Program Files\...\itextsharp.dll"
$pdffiles = Get-ChildItem -File "$folder\*.pdf"
Foreach($file in $pdffiles)
{
$pdf = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $file
$text=[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdf,1)
$startss = $text.LastIndexOf("Completo")
$endss = $text.LastIndexOf("Doc")
$name = $text.Substring($startss +9,$endss - $startss-10)
$startss2 = $text.LastIndexOf("Modalidad")
$endss2 = $text.LastIndexOf("(Entre")
$mode = $text.Substring($startss2 +10,$endss2 - $startss2-10)
Rename-Item -NewName ($name + "-" + $mode + "-" + ".pdf") -Path "$file"
$pdf.Close()
}
Hope someone can help me to make it work, thanks in advance

Related

How to make powershell with itextsharp edit multiple pdfs

I managed to make a script that opens a pdf file, reads it, makes 2 variables with information from it and saves the file using those variables, but i cant make it do that to all the pdf files in a folder. i dont know if anyone can help me. This is what i have so far:
$file = "C:\Users\..." #path to my pdf file
Add-Type -Path "C:\Program Files\...\itextsharp.dll"
$pdf = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $file
$text=[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdf,1)
$startss = $text.LastIndexOf("Completo")
$endss = $text.LastIndexOf("Doc")
$name = $text.Substring($startss +9,$endss - $startss-10)
$startss2 = $text.LastIndexOf("Modalidad")
$endss2 = $text.LastIndexOf("(Entre")
$mode = $text.Substring($startss2 +10,$endss2 - $startss2-10)
$pdf.Close()
Rename-Item -NewName ($name + "-" + $mode + "-" + ".pdf") -Path "$file"
You just need a foreach loop. I would recommend reading about Get-ChildItem if you're not sure what it is and some basics on foreach loops.
$folder = "C:\Users\path\to\pdf folder"
Add-Type -Path "C:\Program Files\...\itextsharp.dll"
$pdfFiles = Get-ChildItem "$folder\*.pdf"
foreach($file in $pdfFiles)
{
$pdf = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $file
$text= [iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($pdf,1)
$startss = $text.LastIndexOf("Completo")
$endss = $text.LastIndexOf("Doc")
$name = $text.Substring($startss +9,$endss - $startss-10)
$startss2 = $text.LastIndexOf("Modalidad")
$endss2 = $text.LastIndexOf("(Entre")
$mode = $text.Substring($startss2 +10,$endss2 - $startss2-10)
$pdf.Close()
Rename-Item -NewName ($name + "-" + $mode + "-" + ".pdf") -Path $file
}

How to loop through column values from a table and create folders via powershell

I'm trying to achieve the following via powershell:
I have a table(TBL_DDL) with 5 columns (CATALOG,SCHEMA,OBJECT_TYPE,OBJECT_NAME,DDL)
Now, i'm extract data from this table and then trying to create a folder structure by concatenating first 4 columns (CATALOG,SCHEMA,OBJECT_TYPE,OBJECT_NAME) in C: drive and then exporting the data in DDL column in txt file.
For eg: C:\"CATALOG"\"SCHEMA"\"OBJECT_TYPE"\"OBJECT_NAME"\DDL.txt
I'm trying to achieve this via powershell. Can anyone help me please?
$SqlCmd = 'snowsql -c example -d tu_test -s public -q "select catalog,schema,OBJECT_TYPE,OBJECT_NAME,DDL from SF_TBL_DDL limit 2"'
$MultiArray = #(Invoke-Expression $SqlCmd)
$dt = New-Object System.Data.Datatable
[void]$dt.Columns.Add("CATALOG")
[void]$dt.Columns.Add("SCHEMA")
$Output = foreach ($Object in $MultiArray)
{
foreach ($SCHEMA in $Object.SCHEMA)
{
$someother = New-Object -TypeName psobject -Property #{CATALOG = $Object.CATALOG; SCHEMA = $SCHEMA}
$nRow = $dt.NewRow()
$nRow.CATALOG = $someother.CATALOG
$nRow.SCHEMA = $someother.SCHEMA
$dt.Rows.Add($nRow)
}
}
$dt.row.count
At the moment, i'm getting 0 rows in $dt.
Cheers
You can use System.Data.DataTable object the pull your result set and then loop through it to perform the required operation.
Here GetTableValues function will retrieve the table values and then use following cmdlet to create directory and file
New-Item -ItemType "directory" -Path $dirPath
New-Item -ItemType "file" -Path $filePath
Complete code looks like this
function GetTableValues(){
$DBConnectionString = "<Your DB connection string>";
$sqlConn = new-object System.Data.SqlClient.sqlConnection $DBConnectionString;
$sqlConn.Open();
$sqlCommand = $sqlConn.CreateCommand();
$sqlCommand.CommandText = "select catalog,[schema],OBJECT_TYPE,OBJECT_NAME,DDL from TBL_DDL"; ##Put your correct query here
$result = $sqlCommand.ExecuteReader();
$table = New-Object System.Data.DataTable;
$table.Load($result);
$sqlConn.Close();
return $table;
}
$tableValue = GetTableValues;
foreach ($Row in $tableValue)
{
$filePath = "C:\" + $Row.catalog.TrimEnd() + "\" + $Row.schema.TrimEnd() + "\" + $Row.OBJECT_TYPE.TrimEnd() + "\" + $Row.OBJECT_NAME.TrimEnd() + "\" + $Row.DDL.TrimEnd() + ".txt"
$dirPath = "C:\" + $Row.catalog.TrimEnd() + "\" + $Row.schema.TrimEnd() + "\" + $Row.OBJECT_TYPE.TrimEnd() + "\" + $Row.OBJECT_NAME.TrimEnd()
New-Item -ItemType "directory" -Path $dirPath ##Creates directory
New-Item -ItemType "file" -Path $filePath ##Creates file in $dirPath directory
}
This works perfectly fine for me.

How to search in PDF files and move them using powershell

I have a large number of PDF files in a folder with several subfolders. In this pile of files I need to find the ones with a specific string and move them to a new destination.
I already have a fine piece of code for the search process that gives me the files needed (thx to the creator) - now I need help to combine this code with a move-function. All the files found by the following code should be moved to a new destination.
$searchString = "text i need to find"
$searchPath = "C:\test"
$sql = "SELECT System.ItemPathDisplay, System.DateModified, "
+ "System.Size, System.FileExtension FROM SYSTEMINDEX "
+ "WHERE SCOPE = '$searchPath' AND FREETEXT('$searchstring')"
$provider = "provider=search.collatordso;extended properties=’application=windows’;"
$connector = new-object system.data.oledb.oledbdataadapter -argument $sql, $provider
$dataset = new-object system.data.dataset
if ($connector.fill($dataset)) { $dataset.tables[0] }
The output is like:
SYSTEM.ITEMPATHDISPLAY SYSTEM.DATEMODIFIED SYSTEM.SIZE SYSTEM.FILEEXTENSION
---------------------- ------------------- ----------- --------------------
C:\test\file.pdf 27.08.2019 19:14:57 17119 .pdf
Thank you for your help!
I found a solution by myself. For anyone interested.
Note: $searchPath must be a local drive on the machine you are running the script on, because the PDF files need to be indexed by the windows search. For that you probably have to install an iFilter: https://superuser.com/questions/402673/how-to-search-inside-pdfs-with-windows-search
$searchString = "Merkblatt für nüchtern eintretende Patienten"
$searchPath = "Y:\"
$targetPath = "\\Server\Path\folder"
$sql = "SELECT System.ItemPathDisplay, System.DateModified, " +
"System.Size, System.FileExtension FROM SYSTEMINDEX " +
"WHERE SCOPE = '$searchPath' AND FREETEXT('$searchstring')"
$provider = "provider=search.collatordso;extended properties=’application=windows’;"
$connector = new-object system.data.oledb.oledbdataadapter -argument $sql, $provider
$dataset = new-object system.data.dataset
if ($connector.fill($dataset)) {
#$dataset.tables[0]
foreach ( $Row in $dataset.tables[0].Rows) {
$targetFile = $Row[0] -replace "^Y:", $targetPath
$targetSubfolder = Split-Path -Path $targetFile
#write-host "Targetfile : $targetFile"
#write-host "Moving: $($Row[0])"
Move-Item -Path $($Row[0]) -Destination $targetPath -Force
}
}

Copy latest file from server to local destination

I've been struggling with a script that needs to copy or download the latest file from a file server to the local drive folder. Here is what i came up with:
[String]$LocalServer = "\\IP_address\D:\Interfaces\"
[String]$File_Name = "MK." + (Get-Date).ToString("ddMMyy") + ".tar.gz" #file name is example MK.040418.tar.gz
[String]$Path = "C:\Localfolder"
[String]$Username = "admin"
[String]$Password = "Admin123"
Copy-Item -Path {$LocalServer + "\" + $FileName} - Destination {$LocalPath}
#$WebClient = New-Object System.Net.WebClient
#$WebClient.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
#$WebClient.DownloadFile($LocalServer, $FileName)
There's a few issues with your code:
You don't need to use {} to wrap parameters with Powershell.
Your variable is $File_Name but you're using $FileName (missing _) with Copy-Item command.
$LocalServer ends with a \, and you're also adding one in with$LocalServer + "\" + $FileName, so the path ends up having a double slash: \\IP_address\D:\Interfaces\\MK.040418.tar.gz
Fixing these points, the command should be:
Copy-Item -Path "$LocalServer$File_Name" -Destination $LocalPath

Get datetaken attribute on file

I am trying to write a script that will get the DATETAKEN attribute from a photo and create a folder structure based on that and move the file to this new location. I have found scripts on google that I'm trying to use but when I running it, it returns:
PS C:\Temp> C:\Temp\MovePhoto.ps1
GAC Version Location
--- ------- -------- True v4.0.30319
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0....
Move-Item : The process cannot access the file because it is being
used by another process. At C:\Temp\MovePhoto.ps1:43 char:5
+ Move-Item $FileFullName "$FileDirFull\$FileBaseNameNU"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\NoBackup\TES...RA\IMG_1372.JPG:FileInfo) [Move- Item],
IOException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
If I do the script without the SystemDrawing line it works. But then I can't get the DATETAKEN attribute. I just can't figure out what I am missing.
Here is the script
[reflection.assembly]::LoadWithPartialName("System.Drawing")
$FileAll = (Get-ChildItem $SourcePath -Recurse | where {!$_.psiscontainer} | Select-Object Name,Fullname,BaseName,Extension,CreationTime,LastWriteTime,Length,#{Name="MD5";Expression={Get-Md5Hash $_.fullname}} | group MD5 | Where {$_.Count -gt 1 } | %{$_.Group} | sort MD5)
foreach ($File in $FileAll) {
$FileBaseName = $File.BaseName
$FileExtension = $File.Extension
$FileFullName = $File.FullName
$FileBaseNameNu = $FileBaseName + $FileExtension
$FileName = $File.Name
}
$foo = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $FileFullName
$date = $foo.GetPropertyItem(36867).Value[0..9]
$arYear = [Char]$date[0],[Char]$date[1],[Char]$date[2],[Char]$date[3]
$arMonth = [Char]$date[5],[Char]$date[6]
$arDay = [Char]$date[8],[Char]$date[9]
$strYear = [String]::Join("",$arYear)
$strMonth = [String]::Join("",$arMonth)
$strDay = [String]::Join("",$arDay)
$DateTaken = $strYear + "-" + $strMonth + "-" + $strDay
$FileLastWriteTime = $File.LastWriteTime
$FileDirYear = $FileLastWriteTime.Year
$FileDirDate = $FileLastWriteTime.ToShortDateString()
$FileDirFull = "$DestinationPath\DUBLETTER\$FileDirYear\$DateTaken"
# Create destination path
if ((Test-Path $FileDirFull) -eq $false) {
New-Item -Path $FileDirFull -ItemType Directory
}
if (Test-Path (Join-Path $FileDirFull $File.Name)) {
$n = 0
while ((Test-Path (Join-Path $FileDirFull $FileBaseNameNU)) -eq $true){
$FileBaseNameNU = $FileBaseName + "-" + ++$n + $FileExtension
}
}
Move-Item $FileFullName "$FileDirFull\$FileBaseNameNU"
}
Can you try to replace
[reflection.assembly]::LoadWithPartialName("System.Drawing")
by
Add-Type -AssemblyName "system.drawing"
Forget it, your trouble is with your file C:\NoBackup\TES...RA\IMG_1372.JPG wich can't be moved because it's open (seems to be open for usage in $foo var). Try first to copy it. You perhaps can use $foo.Dispose() before Move-Item $FileFullName "$FileDirFull\$FileBaseNameNU"
I've done this in VBScript, using GetDetailsOf()... see MSDN
This can be done using PowerShell, see... Scripting Guys
There may be a .NET method way of doing this, i.e.: more "native" to PS.