7MTT Multiple Job Parser

This might be handy for large 7 to C transition projects, to be able to get the outputs of all the 7MTT jobs (we’d mostly be interested in pre-checks) and line them all up side by side into one CSV (a column per job for comparison purposes), which makes it easy to filter on pre-check errors/warnings that either aren’t of interest, or are already known about, and then can focus on just the important stuff.

Its super simple to run on your 7MTT box, just do in PowerShell>


.\7MTT_Job_Parser.ps1


It automatically targets the 7MTT jobs folder. I added some other optional switches:

-FileOrFolder
-PrecheckFlag
-TransitionOp
-FileOut

The tool grabs all the .job files, converts them from JSON, and then generates a CSV. I’ve not currently implemented the “AREA” column (i.e. CIFS/NFS/SAN …), and the “Start Time” output could be improved.

An idea for the future would be to automate 7MTT session setup and running pre-checks - using 7MTT CLI - against any number of systems; then this tool can take the results of those pre-check jobs and parse them into one spreadsheet.

The Script

Note: Formatted for blogger with tabs replaced by two spaces

Copy and paste the below into a text editor and save as 7MTT_Job_Parser.ps1


Param(
  [String]$FileOrFolder,
  [String]$PrecheckFlag,
  [String]$TransitionOp,
  [String]$FileOut = "7MTT_JOBS.CSV"
)

## Use 7MTT jobs folder and/or check specified path exists ##
If(!$FileOrFolder){
  $PathTo7MTTbin = $Env:Path.Split(";") | Where{$_ -match "7-Mode Transition Tool"}
  $PathMinusBin  = $PathTo7MTTbin.Substring(0,$PathTo7MTTbin.length - 4)
  $FileOrFolder  = $PathMinusBin + "\data\jobs"
}
If(!(Test-Path $FileOrFolder)){ Write-Host "Path test to $FileOrFolder failed - exiting!" -ForegroundColor Red; EXIT}

## Put job files to check into an array ##
$FilesToCheck = @()
[Boolean]$IsFolder = (Get-Item $FileOrFolder) -is [System.IO.DirectoryInfo]
If(!$IsFolder){ $FilesToCheck += $FileOrFolder }
else{
  Get-ChildItem -Path $FileOrFolder -Filter *.job | Foreach{ $FilesToCheck += ($FileOrFolder + "\" + $_.Name) }
}
If(!$FilesToCheck){ Write-Host "Not found any job files - exiting!" -ForegroundColor Red; EXIT}

## Simplified Add-Member function (saves typing) ##
$R = @{}
Function AM {
  Param($I,$N,$V)
  If(!$R.$I){$R.$I = New-Object PSObject}
  Add-Member -InputObject $R.$I -MemberType NoteProperty -Name $N -Value $V -Force
}

## Create Column and Side Headings ##
# Col 1         Col 2          Col 3            Col 4            Col 5
AM 2 "1" "2"; AM 2 "2" ""  ; AM 2 "3" ""    ; AM 2 "4" ""    ; AM 2 "5" "Job File Name"
AM 3 "1" "3"; AM 3 "2" ""  ; AM 3 "3" ""    ; AM 3 "4" ""    ; AM 3 "5" "Version"
AM 4 "1" "4"; AM 4 "2" ""  ; AM 4 "3" ""    ; AM 4 "4" ""    ; AM 4 "5" "Session"
AM 5 "1" "5"; AM 5 "2" ""  ; AM 5 "3" ""    ; AM 5 "4" ""    ; AM 5 "5" "Pre-Check Flags"
AM 6 "1" "6"; AM 6 "2" ""  ; AM 6 "3" ""    ; AM 6 "4" ""    ; AM 6 "5" "Transition Op"
AM 7 "1" "7"; AM 7 "2" "ID"; AM 7 "3" "AREA"; AM 7 "4" "TYPE"; AM 7 "5" "Start Time"
AM 8 "1" "8"; AM 8 "2" "=="; AM 8 "3" "===="; AM 8 "4" "===="; AM 8 "5" ""

$Col = 5 # Initialize Column count (current column)
$Row = 8 # Initialize Row count (current row)

$RecordedCodes = @()
$CodesToRow    = @{}

$FilesToCheck | Foreach {
  $J = ConvertFrom-JSON -InputObject (Get-Content $_ -Raw)
  ## Allow if no PreCheckFlag or have match ##
  If(!$PreCheckFlag -or ($J.PreCheckFlags -eq $PrecheckFlag)){
    ## Allow if no TransitionOp or have match ##
    If(!$TransitionOp -or ($J.TransitionOp -eq $TransitionOp)){
      ## Construct Header ##
      $Col++
      $FileName = $_.Split("\")[$_.Split("\").Count - 1]
      AM 2 "$Col" $FileName
      AM 3 "$Col" $J.Version
      AM 4 "$Col" $J.SessionName
      AM 5 "$Col" $J.PreCheckFlags
      AM 6 "$Col" $J.TransitionOp
      AM 7 "$Col" $J.StartTime
      AM 8 "$Col" "====="
      $J.JobResultList | Foreach{
        ## Allow if a numeric Result Code ##
        $ResultCode = $_.Result.Code.Trim()
        If($ResultCode -match "^[-+]?([0-9]*\.[0-9]+|[0-9]+\.?)$"){
          ## Check if we've already had this code ##
          If($RecordedCodes -NotContains $ResultCode){
            $RecordedCodes += $ResultCode
            $CodesToRow.$ResultCode = $Row+1
            $Area = "" # NOT IMPLEMENTED YET
            $ResultType = $_.Result.Type
            AM ($Row+1) "1" ($Row+1); AM ($Row+1) "2" $ResultCode; AM ($Row+1) "3" $Area; AM ($Row+1) "4" $ResultType; AM ($Row+1) "5" "Message"
            AM ($Row+2) "1" ($Row+2); AM ($Row+2) "2" $ResultCode; AM ($Row+2) "3" $Area; AM ($Row+2) "4" $ResultType; AM ($Row+2) "5" "Corrective Action"
            AM ($Row+3) "1" ($Row+3); AM ($Row+3) "2" $ResultCode; AM ($Row+3) "3" $Area; AM ($Row+3) "4" $ResultType; AM ($Row+3) "5" "Affected Objects"
            $Row += 3
          }
          $CodeRow = $CodesToRow.$ResultCode
          AM ($CodeRow)   "$Col" $_.Result.Message
          AM ($CodeRow+1) "$Col" $_.Result.CorrectiveAction
          AM ($CodeRow+2) "$Col" ($_.Result.AffectedObjects.ObjectName | Out-String).Trim()
        }
      }
    }
  }
} # End of $FilesToCheck | Foreach

$CSV = @()
For($i=2;$i -le $Row;$i++){ $CSV += $R.$i }
$CSV | FT
$CSV | Where-Object {$_} | Export-CSV -Path $FileOut -NoTypeInformation


Comments