Rename Files based on rolling files present.

I have multiple servers as Server1, Server2, Server3,…ServerN (N is a finite no)

On Each server I need to search for a specific file File234.deg in specific location as \ServerN\E$\Folder1(No Sub folder search is needed, search is restricted up to Folder1 only)

If file is present I need to rename (rolling backup like .deg01/.deg02) the file (File234.deg) based on condition whether how many rolling files are already there. I need to create next rolling file. For Ex:

  1. If no rolling files are there rename File234.deg to File234.deg01

  2. If rolling files present are File234.deg01 and File234.deg02 then I should rename file to File234.deg03. There is a finite limit to the rolling files numbers too here.

After taking the rolling backup I need to create a fresh empty file with the same name as before File234.deg in the same location

What does your code look like so far? is there a specific point at which you’re stuck?

Hi Richard,

I am new to Power-Shell, so was trying something. so far I am done with the basic completion if the sample script: Please help me to optimize this further.

##Reading server paths from a file
$filePaths = $var = Get-Content -Path ‘\ServerMachine1\E$\RollingAudFile\Paths.txt’
##File pattern trying to look for
$fileName = ‘File234.deg’
$items = @()
$num
##log file
$Logfile = “\ServerMachine1\E$\RollingAudFile\Logs\RollingAudFile.log”

##Function to write application log
Function LogWrite
{
Param ([string]$logstring)
$Level = ‘INFO’
$Stamp = (Get-Date).toString(“yyyy-MM-dd HH:mm:ss:fff”)

$Line = “$Stamp $Level $logstring”

Add-content $Logfile -value $Line
}
##Criteria for file renaming
function Find-Date
{
Param ([string]$firstLine)

 $var = $firstLine.Substring(0,22)

$var1 = $var.Replace(“'”, “”)
$date = $var1.Replace(“,”, " ")

LogWrite "Oldest entry is from $date"

return $date
}
##String to Date conversion method
function Convert-StringToDateTime
{
param
(
[Parameter(Mandatory = $true)]
[String] $DateTimeStr
)

$DateTimeParts = $DateTimeStr -split ’ ’

$DateParts = $DateTimeParts[0] -split ‘/|-|.’

$DateFormatParts = (Get-Culture).DateTimeFormat.ShortDatePattern -split ‘/|-|.’
$Month_Index = ($DateFormatParts | Select-String -Pattern ‘M’).LineNumber - 1
$Day_Index = ($DateFormatParts | Select-String -Pattern ‘d’).LineNumber - 1
$Year_Index = ($DateFormatParts | Select-String -Pattern ‘y’).LineNumber - 1

$TimeParts = $DateTimeParts[1…$($DateTimeParts.Count - 1)]

if (@($TimeParts).Count -eq 2)
{
$TimeFormatParts = (Get-Culture).DateTimeFormat.ShortTimePattern -split ’ ’

$TT_Index = ($TimeFormatParts | Select-String -Pattern ‘t’).LineNumber - 1
$Time_Index = 1 - $TT_Index

$Time = $TimeParts[$Time_Index,$TT_Index] -join ’ ’
}
else
{
$Time = $TimeParts
}

$DateTime = [DateTime] $($($DateParts[$Month_Index,$Day_Index,$Year_Index] -join ‘/’) + ’ ’ + $Time)

$curDate = Get-Date
$TimeSpan =  $curDate - $DateTime
$daysNum = $TimeSpan.TotalDays;

return $daysNum
}

try
{
$(foreach($filePath in $filePaths)
{
$files = @()
LogWrite “Checking .deg file at $filePath”
$items = Get-ChildItem $filePath

$(foreach($item in $items)
{
$(if($item.Name -match $fileName)
{
$files += $item
})
})
$num = $files.Length
LogWrite “Total no of valid .deg files at $filePath are $num”
$num–

if((($files[0]).length -lt 1mb) -and (($files[0]).length -gt 0kb))
{
$file = $filePath + $files[0].Name
LogWrite “Size of $file is less than 1MB”
$var = Get-Content -Path $file | Select-Object -First 1

$date = Find-Date $var

$daysNum = Convert-StringToDateTime $date

if($daysNum -gt 14)
{
LogWrite “PerfDeg file is $daysNum days old, Rolling of file is needed.”
$(if($num -lt 10)
{
rename-item -path $filePath\File234.deg -newname File234.deg0$num
}
else
{
rename-item -path $filePath\File234.deg -newname $fileName$num
})
New-Item $filePath\File234.deg -ItemType file

            LogWrite 'Rolling file Completed'
        }
        else {LogWrite "PerfDeg file is $daysNum days old, Rolling of file is not needed."}
    }
    else {LogWrite "$files[0] file size is either empty file or more than 1MB so this is not a candidate."}

})
}
Catch
{
$ErrorMessage = $.Exception.Message
$FailedItem = $
.Exception.ItemName
LogWrite “Error at $FailedItem. The error message: $ErrorMessage”
Break
}

Moreover Add-content $Logfile -value $Line this command is throwing error as
Add-content : The network name cannot be found.
At line:3 char:1

  • Add-content $Logfile -value “Log Value start here”
  •   + CategoryInfo          : WriteError: (\\ServerMachine1\E$\L...LogFile.log:String) [Add-Content], IOException
      + FullyQualifiedErrorId : GetContentWriterIOError,Microsoft.PowerShell.Commands.AddContentCommand</em> when I am trying to give network path as <strong>"$Logfile = "\\ServerMachine1\E$\RollingAudFile\Logs\RollingAudFile.log""</strong>
    
    

But when I am passing path as “$Logfile = “E:\RollingAudFile\Logs\RollingAudFile.log”” then it is fine. Why so?
I am running this from ServerMachine1 only

$serverlist = 'localhost','localhost'

# Parallel Processing
Invoke-Command -ComputerName $serverlist {
    # Sort numbers in extension
    $list = Get-ChildItem "\\ServerN\E$\Folder1" -Filter File234.* | 
    Select-Object Name,@{name='Num';exp={[int]($_.Extension -replace '.deg')}} | 
    Sort-Object Num

    # Get last number in array
    $lastnum = $list[-1].Num
    $newnum = $lastnum + 1
    $newname = "File234.deg$newnum"

    Rename-Item -Path "\\ServerN\E$\Folder1\File234.deg" -NewName $newname -ErrorAction SilentlyContinue
}