Rename-LayoutFileForTFS.ps1
function Rename-LayoutFileForTFS { ############################################################### # # This function will rename source file to match <FILENAME>_<LAYOUT_TYPE>_<LAYOUT_ID>.<EXTENSION> format # # The Layout ID Tag is set in the Get-LayoutTagName() function # # TM MD # ############################################################### param ( [parameter(Mandatory=$true)] [string]$layoutFileName, [parameter] [ValidateSet('RDL','DOCX')] [string]$layoutType, [switch]$keepOriginal ) # initialisation $layoutId = "" $file = Get-Item $layoutFileName # check if layout is set and, if not, derive one from the file extension if (($layoutType -eq '') -or ($layoutType -eq $nill)) { $layoutTypeString = $file.Extension.ToString().ToUpper().TrimStart('.') } else { $layoutTypeString = $layoutType.ToString() } # get the layout ID from corresponding layout file type switch ($layoutTypeString) { 'RDL' {$layoutId = Get-LayoutIDTAgValueForRDL -layoutFileName $layoutFileName} 'DOCX' {$layoutId = Get-LayoutIDTAgValueForWRD -layoutFileName $layoutFileName} default {throw "Unable to determin the layout type for $layoutFileName..."} } # error if layout id is not identified if (($layoutId -eq '') -or ($layoutId -eq $nill)) { Write-Error "Unable to find $(Get-LayoutTagName) tag in the $layoutFileName..." break } # generate a new file name $newFileName = "$($file.FullName.TrimEnd($file.Extension))_$($layoutTypeString)_$($layoutId)$($file.Extension)" # rename or copy the file, depending on the switch if (!($keepOriginal)) { Rename-Item -Path $layoutFileName -NewName $newFileName Write-Output "$newFileName renamed to $newFileName..." } else { Copy-Item -Path $layoutFileName -Destination $newFileName Write-Output "$newFileName is created..." } } function Get-LayoutIDTAgValueForRDL { ############################################################### # # This function will find relevant variable in the RDL and return this variable value # # NB! This function will leave a copy of the file being renamed in the TEMP folder. Could not find a way to unlock the file after accessing it via Zip assembly. # # TM MD # ############################################################### param( [parameter(Mandatory=$true)] [string]$layoutFileName ) $layoutFile = Get-Item $layoutFileName $xmlDoc = New-Object System.Xml.XmlDocument $xmlDoc.load($layoutFile) foreach ($var in $xmlDoc.GetElementsByTagName('Variable')) { if ($var.Name -eq $(Get-LayoutTagName)) { return $var.Value } } } function Get-LayoutIDTAgValueForWRD { ############################################################### # # This function will use the Zip assembly to find the core.xml file in the relevant .docx and will read the relevant tag in the keywords element and return it's value # The layout ID tag is stored as <TAGNAME>:<TAGVALUE> # # NB! This function will leave a copy of the file being renamed in the TEMP folder. Could not find a way to unlock the file after accessing it via Zip assembly. # # TM MD # ############################################################### param( [parameter(Mandatory=$true)] [string]$layoutFileName ) # check .Net version $sysEnvVer = [System.Environment]::Version if (!($sysEnvVer.Major -ge 4 -and $sysEnvVer.Build -ge 30319)) {throw "DotNet Framework 4.5 is not installed"} # load Compression assembly to use ZipFile library [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') # copy the item to the TEMP folder to avoid any corruption $tempFileName = "$env:TEMP\$([guid]::NewGuid())" copy-item -Path $layoutFileName -Destination $tempFileName # get core.xml from the .docx file (no extraction) $coreXml = [IO.Compression.ZipFile]::OpenRead($tempFileName).Entries | where "Name" -eq "custom.xml" # load core.xml content into xmlDom $xmlDoc = New-Object System.Xml.XmlDocument $xmlDoc.load($coreXml.Open()) # find cp:keywords elements - this is where the tags are stored; foreach ($keyword in $xmlDoc.GetElementsByTagName('property')) { $keywordValue = $keyword.name if ($keywordValue -eq $(Get-LayoutTagName)) { return $keyword.lpwstr } } } function Get-LayoutTagName { return 'TM_LAYOUT_ID' } Export-ModuleMember -Function Rename-LayoutFileForTFS |