Powershell Rename Files in Directory based on File Contents

Requirements: I have some files from an external system, and I want to promote some data from inside the file to the file name itself.

Example, original filename: PO_287783.xml
Desired filename: PO_287783_TransID_9081631_Lines_3.xml

I want to peek into the file an pull out the Transaction ID, and also get a count of how many line items are on this PO. Each line item in this case is in an XML element called G_LINES.

In this specific example, the TransactionID is not the value of an XML element, but only a partial value, so have to do some parsing. It’s found in a row like this:

I want to be able to run the script multiples times, when no files appear in the directory, and it shouldn’t try to rename files that have already been renamed (so it checks for the presence of the phrase “TRANS” in the filename).

Sample Code:

$retentionDays = 30
$formatDateTime = get-date -f _yyyy_MM_dd__HH_mm_ss
$formatDate = get-date -f _yyyy_MM_dd
Write-Host “formatDateTime= $formatDateTime”
Write-Host “——————————————————-”
$renameCount = 0
$skipCount = 0
$deleteCount = 0

# Array of Directory Names (logic below will process each directory you specify here)
$dirNames = “c:\temp\BizTalkTest\PORouting\InBoxFromFTP”  #you can add comma separately list of directories here 

Foreach ($dirName in $dirNames)
    Write-Host “DirName=$dirName”
    $files = Get-ChildItem $dirName -Filter *.xml 
    ForEach ($file in $files) 
        $fileContents = [System.IO.File]::ReadAllText($file.FullName)

        #example: <POH_NOTE_TO_VENDOR>10998-9081635||X</POH_NOTE_TO_VENDOR> 

        $lineHeader = "<G_LINES>"
        $countLines = ([regex]::Matches($fileContents, "$lineHeader" )).count
        Write-Host "countLines=$countLines" 

        $posTransIDInFileName = $file.Name.IndexOf("Trans") 
        if ($posTransIDInFileName -eq -1)   #if file already had Trans in the filename, don't rename it again 

            $searchString = "<POH_NOTE_TO_VENDOR>10998-"
            $pos1 = $fileContents.IndexOf($searchString); 
            if ($pos1 -gt 0) 
                 $pos2 = $fileContents.IndexOf("||",$pos1) 
                 if ($pos2 -gt 0) 
                    $startCapture = $pos1 + $searchString.Length 
                    $captureLength = $pos2 - $startCapture 
                    Write-Host "StartCapture=$startCapture CaptureLength=$CaptureLength" 
                    $TransID = $fileContents.Substring($startCapture,$captureLength); 
                    Write-Host "TransId=" + $TransID 

                    $newFilename = $file.Name.Replace(".xml","_TransID_$TransID.xml"); 
                    $newFilename = $file.Name.Replace(".xml","_Lines_$countLines.xml"); 
                    write-Host $newFilename
                    Rename-Item $file.FullName $newFileName


    } #end of ForEach $file 

}  #end of ForEach $dirName 


Leave a Reply