PowerShell: Fob-Viewer mit Filter- und Sortiermöglichkeit

2. August 2015 00:45

Mit diesem Skript wird der Dateiheader einer Fob-Datei ausgelesen und in einem Datagrid (Out-GridView) angezeigt. Die Spalten können dort frei arrangiert und alles gefiltert und sortiert werden.

Edit 24.10.17: Für manuellen Betrieb ist hier eine Variante mit "Datei öffnen"-Fenster.

Bitte beachten: Die Versionsliste für ein Objekt ist in einer Fob ggf. nur unvollständig vorhanden, die maximale Länge dort ist nur 67 Zeichen (statt 80 bzw. 248 ab NAV 2013 R2).
Deswegen habe ich das Feld abweichend nur Version genannt :wink: .

FobViewer1.jpg

Filtern im Feld Name auf "Terms"
FobViewer2.jpg

Ein Filter über alle Felder mit "Co". Es wäre schön, wenn der NAV-Windowsclient das auch optional könnte :mrgreen: .
FobViewer3.jpg

Kombinierte Mehrfachfilter mit einstellbaren Filterkriterien
Fobviewer5.png

Filterung auf Type "Re" (= Reports) auf diese dann nach Namen sortiert. Bei Sortierung nach ID beachten, dass alle Felder als Text behandelt werden.
FobViewer4.jpg

Die Übergabe der Objektliste nach Excel ist über die Zwischenablage ebenfalls möglich.

Die Funktion wird zusammen mit dem Pfad zur Fobdatei aufgerufen.
Code:
    function FobObjectsGridView

    {
    $FileExists = Test-Path $args
    If ($FileExists -eq $False) {Throw "No $args file exists at this location."}
    $FileExtension = [System.IO.Path]::GetExtension($args)
    if ($FileExtension -eq '.fob')

    {
    $DataArray = New-Object System.Collections.Generic.List[object]
    $reader = [System.IO.File]::OpenText($args)
    Write-host "Reading fob header, please wait..."
    try {
        for(;;) {
            $line = $reader.ReadLine()
            if ($line -eq $null) { break }
            $FirstCharacter = $line.Substring(0,1)
            IF ([byte][char]$FirstCharacter -eq 26) { break }
            if ($FirstCharacter -ne ' ')
            {           
            Write-host $line
            $ObjectType = $line.Substring(0,9).Trim()
            $ObjectID = $line.Substring(10,10).Trim()
            $ObjectName = $line.Substring(21,30)
            $ObjectDate = $line.Substring(54,10).Trim()
            $ObjectTime = $line.Substring(70,8).Trim()
            }
            else
            {
            $ObjectSize = $line.Substring(10,10)
            $ObjectVersion = $line.Substring(21,57)
            $Obj =  New-Object Psobject -Property @{
                   Type= $ObjectType
                   ID =  $ObjectID
                   Name = $ObjectName
                    Date = $ObjectDate
                    Time = $ObjectTime
                    Size = $ObjectSize
                    Version = $ObjectVersion
                     }
                    $DataArray.add($Obj)

            }
        }
    }
    finally {
            $reader.Close()
            $DataArray | Out-GridView  -title "Fobviewer $args"

       }
    }
    else
      {Throw 'Please use a Dynamics NAV object file with *.fob extension for this script.'}
    }


Tags: Fobviewer
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Objektzähler, Out-GridView wait-Schalter

11. August 2015 23:46

Mit dieser Variante kommen Objektzähler für die Gesamtanzahl und die der jeweils in der Fob-Datei vorhandenen Objekte dazu, die zusammen mit dem Dateinamen in der Titelleiste angezeigt werden.
Außerdem wird geprüft, ob das Skript in der Konsole läuft ($host.name -eq 'ConsoleHost', z.B. Ausführung wie hier nach Anpassung direkt, dann ist beim Aufruf von Out-GridView der Parameter -wait notwendig, um die Konsole und GridView offenzuhalten und nach Schließen der GridView die Konsole automatisch mit zu schließen) oder nicht, in dem ISE können ohne -wait mehrere GridViews nacheinander geöffnet werden.
FobViewObjCnt.jpg

Obiges Bild ist mit Windows 10 enstanden, hier unter Windows 7 mit Hervorhebung der neuen Infofelder:
FobViewerCounter.png

Code:
       
function FobObjectsCntGridView
{
$FileExists = Test-Path $args
If ($FileExists -eq $False) {Throw "No $args file exists at this location."}
$FileExtension = [System.IO.Path]::GetExtension($args)
if ($FileExtension -eq '.fob')
{
[int]$OBJCnt = 0
[int]$TABCnt = 0
[int]$FORCnt = 0
[int]$PAGCnt = 0
[int]$REPCnt = 0
[int]$DATCnt = 0
[int]$CODCnt = 0
[int]$QUECnt = 0
[int]$XMLCnt = 0
[int]$MENCnt = 0
$DataArray = New-Object System.Collections.Generic.List[object]
$reader = [System.IO.File]::OpenText($args)
Write-host "Reading fob header, please wait..."
try {
   for(;;) {
      $line = $reader.ReadLine()
      if ($line -eq $null) { break }
      $FirstCharacter = $line.Substring(0,1)
      IF ([byte][char]$FirstCharacter -eq 26) { break }
      $ShortObjectType = $line.Substring(0,3).ToUpper()
      Switch ($ShortObjectType)
      {
      "TAB" {$TABCnt++}
      "PAG" {$PAGCnt++}
      "REP" {$REPCnt++}
      "COD" {$CODCnt++}
      "QUE" {$QUECnt++}
      "XML" {$XMLCnt++}
      "MEN" {$MENCnt++}
      "FOR" {$FORCnt++}
      "DAT" {$DATCnt++}
      }
      if ($FirstCharacter -ne ' ')
      {           
      $OBJCnt++
      $ObjectType = $line.Substring(0,9).Trim()
      $ObjectID = $line.Substring(10,10).Trim()
      $ObjectName = $line.Substring(21,30)
      $ObjectDate = $line.Substring(54,10).Trim()
      $ObjectTime = $line.Substring(70,8).Trim()
      }
      else
      {
      $ObjectSize = $line.Substring(10,10)
      $ObjectVersion = $line.Substring(21,57)
      $Obj =  New-Object Psobject -Property @{
            Type= $ObjectType
            ID =  $ObjectID
            Name = $ObjectName
            Date = $ObjectDate
            Time = $ObjectTime
            Size = $ObjectSize
            Version = $ObjectVersion
             }
            $DataArray.add($Obj)

      }
   }
}
finally {
      $reader.Close()
      if ($TABCnt -gt 0) {$ObjectList += "TAB:$TABCnt "}
      if ($FORCnt -gt 0) {$ObjectList += "FOR:$FORCnt "}
      if ($PAGCnt -gt 0) {$ObjectList += "PAG:$PAGCnt "}
      if ($REPCnt -gt 0) {$ObjectList += "REP:$REPCnt "}
      if ($DATCnt -gt 0) {$ObjectList += "DAT:$DATCnt "}
      if ($CODCnt -gt 0) {$ObjectList += "COD:$CODCnt "}
      if ($QUECnt -gt 0) {$ObjectList += "QUE:$QUECnt "}
      if ($XMLCnt -gt 0) {$ObjectList += "XML:$XMLCnt "}
      if ($MENCnt -gt 0) {$ObjectList += "MEN:$MENCnt "}
      
       
      if ($host.name -eq 'ConsoleHost')
      {$DataArray | Out-GridView  -title "Fobviewer $args  $OBJCnt Objects ($ObjectList)" -wait}
      else
      {$DataArray | Out-GridView  -title "Fobviewer $args  $OBJCnt Objects ($ObjectList)"}
   }
}
else
  {Throw 'Please use a Dynamics NAV object file with *.fob extension for this script.'}
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: PowerShell: Fob-Viewer mit Filter- und Sortiermöglichkei

2. August 2016 14:05

Vielen Dank dafür Kowa :)

Ich habe mir daraus ein "Export Objects Via Fob" gebastelt und sehe noch sehr viel mehr Anwendungsmöglichkeiten!
Diese Funktion hier brauche ich nun beim Upgrade/Mergen von Modulen :)

Code:
function NAV.ExportObjectsViaFob {
    [CmdLetBinding()]
    param(

        [string] $databaseServer,
        [string] $database,
        [string] $fobPath,
        [string] $exportPath,
        [string] $NAVVersion="2016"
        )   

    $FileExists = Test-Path $fobPath
    If ($FileExists -eq $False) {Throw "No $fobPath file exists at this location."}
    $FileExtension = [System.IO.Path]::GetExtension($fobPath)
    if ($FileExtension -eq '.fob') {

        ## Needed NAV Sources 90=2016
        if ($NAVVersion -eq "2015"){
            $VersionCode = "80"
        }

        if ($NAVVersion -eq "2016"){
            $VersionCode = "90"
        }

        write-Host -ForegroundColor DarkGray "Load NAV PS Tools from Version $($NAVVersion)/$($VersionCode)..."
        Import-Module "C:\Program Files (x86)\Microsoft Dynamics NAV\$($VersionCode)\RoleTailored Client\Microsoft.Dynamics.Nav.Model.Tools.psd1" -WarningAction SilentlyContinue | out-null
        Import-Module "C:\Program Files\Microsoft Dynamics NAV\$($VersionCode)\Service\NavAdminTool.ps1" -WarningAction SilentlyContinue | Out-Null


        [int]$OBJCnt = 0
        [int]$TABCnt = 0
        [int]$FORCnt = 0
        [int]$PAGCnt = 0
        [int]$REPCnt = 0
        [int]$DATCnt = 0
        [int]$CODCnt = 0
        [int]$QUECnt = 0
        [int]$XMLCnt = 0
        [int]$MENCnt = 0

        $DataArray = New-Object System.Collections.Generic.List[object]
        $reader = [System.IO.File]::OpenText($fobPath)
        Write-host "Reading fob header, please wait..."
        try {
            for(;;) {
                $line = $reader.ReadLine()
                if ($line -eq $null) { break }
                $FirstCharacter = $line.Substring(0,1)
                IF ([byte][char]$FirstCharacter -eq 26) { break }
                $ShortObjectType = $line.Substring(0,3).ToUpper()
                Switch ($ShortObjectType)
                {
                "TAB" {$TABCnt++}
                "PAG" {$PAGCnt++}
                "REP" {$REPCnt++}
                "COD" {$CODCnt++}
                "QUE" {$QUECnt++}
                "XML" {$XMLCnt++}
                "MEN" {$MENCnt++}
                "FOR" {$FORCnt++}
                "DAT" {$DATCnt++}
                }
                if ($FirstCharacter -ne ' ')
                {           
                $OBJCnt++
                $ObjectType = $line.Substring(0,9).Trim()
                $ObjectID = $line.Substring(10,10).Trim()
                $ObjectName = $line.Substring(21,30)
                $ObjectDate = $line.Substring(54,10).Trim()
                $ObjectTime = $line.Substring(70,8).Trim()
                }
                else
                {
                $ObjectSize = $line.Substring(10,10)
                $ObjectVersion = $line.Substring(21,57)
                $Obj =  New-Object Psobject -Property @{
                    Type= $ObjectType
                    ID =  $ObjectID
                    Name = $ObjectName
                    Date = $ObjectDate
                    Time = $ObjectTime
                    Size = $ObjectSize
                    Version = $ObjectVersion
                        }
                    $DataArray.add($Obj)

                }
            }
        }
        finally {
            $reader.Close()
            if ($TABCnt -gt 0) {$ObjectList += "TAB:$TABCnt "}
            if ($FORCnt -gt 0) {$ObjectList += "FOR:$FORCnt "}
            if ($PAGCnt -gt 0) {$ObjectList += "PAG:$PAGCnt "}
            if ($REPCnt -gt 0) {$ObjectList += "REP:$REPCnt "}
            if ($DATCnt -gt 0) {$ObjectList += "DAT:$DATCnt "}
            if ($CODCnt -gt 0) {$ObjectList += "COD:$CODCnt "}
            if ($QUECnt -gt 0) {$ObjectList += "QUE:$QUECnt "}
            if ($XMLCnt -gt 0) {$ObjectList += "XML:$XMLCnt "}
            if ($MENCnt -gt 0) {$ObjectList += "MEN:$MENCnt "}
     
       
            if ($host.name -eq 'ConsoleHost')
            {
                # $DataArray | Out-GridView  -title "Fobviewer $fobPath  $OBJCnt Objects ($ObjectList)" -wait
       
            }
            else
            {
                # $DataArray | Out-GridView  -title "Fobviewer $fobPath  $OBJCnt Objects ($ObjectList)"       
            }


            foreach($Object in $DataArray)
            {
                write-host "export start $($Object.Type)$($Object.id)"
                Export-NAVApplicationObject -ExportTxtSkipUnlicensed -DatabaseName $database -DatabaseServer $databaseServer -Path "$($exportPath)\$($Object.Type)-$($Object.id).txt" -Filter "Type=$($Object.Type);ID=$($Object.id)" -Force
            }

                       

          }
        } else {
            Throw 'Please use a Dynamics NAV object file with *.fob extension for this script.'
        }

}


So Rufe ich die Funktion auf:
Code:
# Aufruf:
NAV.ExportObjectsViaFob -databaseServer "MyLaptop\NAVDEMO" -database "MYDB" -fobPath "C:\AAA RDP share\NewObjects.fob" -exportPath "C:\AAA RDP share\NewObjectsFromDatabase"

Fob-Viewer mit "Datei öffnen" -Fenster

24. Oktober 2017 10:25

Auch vom Fobviewer gibt es nun eine Variante mit "Datei öffnen"- Dialogfenster für den manuellen Betrieb.
FobViewer.png


Mit Objektzähler
Code:
function FobObjectsCntGridViewCntDlg
{

$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'

Function Get-FileName($initialDirectory)
 {
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "NAV Fob file (*.fob)|*.fob"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
 }

$inputfile = Get-FileName -initialDirectory "$env:HOMEDRIVE\temp"
if ($inputfile -eq "") {throw 'Please select a file'}

$FileExists = Test-Path $inputfile
If ($FileExists -eq $False) {Throw "No $inputfile file exists at this location."}
$FileExtension = [System.IO.Path]::GetExtension($inputfile)
if ($FileExtension -eq '.fob')
{
[int]$OBJCnt = 0
[int]$TABCnt = 0
[int]$FORCnt = 0
[int]$PAGCnt = 0
[int]$REPCnt = 0
[int]$DATCnt = 0
[int]$CODCnt = 0
[int]$QUECnt = 0
[int]$XMLCnt = 0
[int]$MENCnt = 0
$DataArray = New-Object System.Collections.Generic.List[object]
$reader = [System.IO.File]::OpenText($inputfile)
Write-host "Reading fob header, please wait..."
try {
   for(;;) {
      $line = $reader.ReadLine()
      if ($line -eq $null) { break }
      $FirstCharacter = $line.Substring(0,1)
      IF ([byte][char]$FirstCharacter -eq 26) { break }
      $ShortObjectType = $line.Substring(0,3).ToUpper()
      Switch ($ShortObjectType)
      {
      "TAB" {$TABCnt++}
      "PAG" {$PAGCnt++}
      "REP" {$REPCnt++}
      "COD" {$CODCnt++}
      "QUE" {$QUECnt++}
      "XML" {$XMLCnt++}
      "MEN" {$MENCnt++}
      "FOR" {$FORCnt++}
      "DAT" {$DATCnt++}
      }
      if ($FirstCharacter -ne ' ')
      {           
      $OBJCnt++
      $ObjectType = $line.Substring(0,9).Trim()
      $ObjectID = $line.Substring(10,10).Trim()
      $ObjectName = $line.Substring(21,30)
      $ObjectDate = $line.Substring(54,10).Trim()
      $ObjectTime = $line.Substring(70,8).Trim()
      }
      else
      {
      $ObjectSize = $line.Substring(10,10)
      $ObjectVersion = $line.Substring(21,57)
      $Obj =  New-Object Psobject -Property @{
            Type= $ObjectType
            ID =  $ObjectID
            Name = $ObjectName
            Date = $ObjectDate
            Time = $ObjectTime
            Size = $ObjectSize
            Version = $ObjectVersion
             }
            $DataArray.add($Obj)

      }
   }
}
finally {
      $reader.Close()
      if ($TABCnt -gt 0) {$ObjectList += "TAB:$TABCnt "}
      if ($FORCnt -gt 0) {$ObjectList += "FOR:$FORCnt "}
      if ($PAGCnt -gt 0) {$ObjectList += "PAG:$PAGCnt "}
      if ($REPCnt -gt 0) {$ObjectList += "REP:$REPCnt "}
      if ($DATCnt -gt 0) {$ObjectList += "DAT:$DATCnt "}
      if ($CODCnt -gt 0) {$ObjectList += "COD:$CODCnt "}
      if ($QUECnt -gt 0) {$ObjectList += "QUE:$QUECnt "}
      if ($XMLCnt -gt 0) {$ObjectList += "XML:$XMLCnt "}
      if ($MENCnt -gt 0) {$ObjectList += "MEN:$MENCnt "}
     
       
      if ($host.name -eq 'ConsoleHost')
      {$DataArray | Out-GridView  -title "Fobviewer $inputfile  $OBJCnt Objects ($ObjectList)" -wait}
      else
      {$DataArray | Out-GridView  -title "Fobviewer $inputfile  $OBJCnt Objects ($ObjectList)"}
   }
}
else
  {Throw 'Please use a Dynamics NAV object file with *.fob extension for this script.'}
}


Ohne Objektzähler
Code:
       
function FobObjectsGridViewDlg

        {
        $ErrorActionPreference = "Stop"
        $PSDefaultParameterValues['*:ErrorAction']='Stop'
        Function Get-FileName($initialDirectory)
         {
         [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
   
        $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
        $OpenFileDialog.initialDirectory = $initialDirectory
        $OpenFileDialog.filter = "NAV Fob file (*.fob)|*.fob"
        $OpenFileDialog.ShowDialog() | Out-Null
        $OpenFileDialog.filename
         }
       
        $inputfile = Get-FileName -initialDirectory "$env:HOMEDRIVE\temp"
        if ($inputfile -eq "") {throw 'Please select a file'}
       
       
        $FileExists = Test-Path $inputfile
        If ($FileExists -eq $False) {Throw "No $inputfile file exists at this location."}
        $FileExtension = [System.IO.Path]::GetExtension($inputfile)
        if ($FileExtension -eq '.fob')

        {
        $DataArray = New-Object System.Collections.Generic.List[object]
        $reader = [System.IO.File]::OpenText($inputfile)
        Write-host "Reading fob header, please wait..."
        try {
            for(;;) {
                $line = $reader.ReadLine()
                if ($line -eq $null) { break }
                $FirstCharacter = $line.Substring(0,1)
                IF ([byte][char]$FirstCharacter -eq 26) { break }
                if ($FirstCharacter -ne ' ')
                {           
                Write-host $line
                $ObjectType = $line.Substring(0,9).Trim()
                $ObjectID = $line.Substring(10,10).Trim()
                $ObjectName = $line.Substring(21,30)
                $ObjectDate = $line.Substring(54,10).Trim()
                $ObjectTime = $line.Substring(70,8).Trim()
                }
                else
                {
                $ObjectSize = $line.Substring(10,10)
                $ObjectVersion = $line.Substring(21,57)
                $Obj =  New-Object Psobject -Property @{
                       Type= $ObjectType
                       ID =  $ObjectID
                       Name = $ObjectName
                        Date = $ObjectDate
                        Time = $ObjectTime
                        Size = $ObjectSize
                        Version = $ObjectVersion
                         }
                        $DataArray.add($Obj)

                }
            }
        }
        finally {
                $reader.Close()
                $DataArray | Out-GridView  -title "Fobviewer $inputfile"

           }
        }
        else
          {Throw 'Please use a Dynamics NAV object file with *.fob extension for this script.'}
        }
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.