PowerShell: Export-NAVApplicationObjectFile mit Serverwahl

21. Juli 2014 17:05

Waldo hat hier eine Funktion erstellt, um NAV-Objekte direkt mittels der PowerShell zu exportieren, damit man nicht zwischendurch umständlich auf die cmd-Umgebung wechseln muss. ExportObjects als finsql.exe-Parameter kann ab NAV 2013 genutzt werden.
2 Korrekturen waren auf meinem System notwendig, um das auf meinem Win 7 zum Laufen zu bringen (betriebssystembedingte Unterschiede zwischen Win 7 und 8 bzw. Win 10):
  • Im Code wurde in Zeile 18 ein " vor C:\Program eingefügt
  • Beim WorkingFolder-Parameter am Ende kein \.
Für Win 10 bzw. Win 8 die obigen Änderungen also nicht umsetzen, das Skript funktioniert da sonst nicht mehr.

Im Code unten ist außerdem eine Erweiterung um einen fünften Parameter enthalten, um zusätzlich auch den Servernamen flexibel angeben zu können.
Code:
function Export-NAVApplicationObjectFileFlexiServer

{
 [CmdletBinding()]param (
 [String]$WorkingFolder,
 [String]$ExportFile,
 [String]$Server,
 [String]$Database,
 [String]$Filter )


 $LogFile = "$WorkingFolder\Log_$ExportFile"
 $ExportFile = "$WorkingFolder\$ExportFile"


 if (Test-Path "$WorkingFolder\navcommandresult.txt") {Remove-Item "$WorkingFolder\navcommandresult.txt"}
 if (test-path $ExportFile) {remove-item $ExportFile}

 $NAVFolder = '"C:\Program Files (x86)\Microsoft Dynamics NAV\71\RoleTailored Client'
 $exportfinsqlcommand = """$NAVFolder\finsql.exe"" command=exportobjects,file=$ExportFile,servername=$Server,database=$Database,Logfile=$LogFile"
 if ($Filter -ne ""){$exportfinsqlcommand = "$exportfinsqlcommand,filter=$Filter"}
 $Command = $exportfinsqlcommand
 Write-Debug $Command
 cmd /c $Command

 $ExportFileExists = Test-Path "$ExportFile"
 If (-not $ExportFileExists) {
   write-error "Error on exporting to $ExportFile. Look at the information below."
   if (Test-Path "$WorkingFolder\navcommandresult.txt"){Type "$WorkingFolder\navcommandresult.txt"}
   if (Test-Path $LogFile) {type $LogFile}
 }
 else{
   $NAVObjectFile = Get-ChildItem $ExportFile
   if ($NAVObjectFile.Length -eq 0) { Remove-Item $NAVObjectFile }
   if (Test-Path "$WorkingFolder\navcommandresult.txt") { Type "$WorkingFolder\navcommandresult.txt"}
 }
}

Beispielaufruf in der PowerShell:
Code:
Export-NAVApplicationObjectFileFlexiServer `
 -WorkingFolder 'C:\Merge\Export' `
 -ExportFile '<MyExportFileName>.txt' `
 -Server '<MyServername>' `
 -Database '<MyDatabaseName>' `
 -Filter 'Version List="<MyFilter>"'

In der Praxis kann das dann so aussehen:
Export-NAVApp1.png


Damit diese Funktion direkt nach dem Aufruf genutzt werden kann, muss man diese in der Profildatei dazutragen.
PS_Profile3.png


Um die Ausgabe des Commandstrings mittels Write-Debug zu nutzen, kann man ggf.
Code:
$DebugPreference = "Continue"

am Anfang des Scripts dazuschreiben.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Anlegen der Standardmergeordner

22. Juli 2014 15:12

Hilfsfunktion zum Eintragen in die Profildatei, um in der PowerShell im aktuellen Verzeichnis die Standardmergeordner (Merging Application Object Source Files) anzulegen. Diese kann dann alternativ über den Alias cmf aufgerufen werden, der in der letzten Zeile zugewiesen wird.

Code:
# Anlegen der Standard-Mergeordner im aktuellen Verzeichnis
function CreateMergeFolders

{
  md ORIGINAL
  md MODIFIED
  md TARGET
  md RESULT
}

Set-Alias cmf CreateMergeFolders

StandardMergeordner.png


md ist hierbei auch ein Alias, verweist auf mkdir, hinter mkdir "versteckt" sich dann das eigentliche Cmdlet : New-Item, welches wiederum noch einen zweiten Alias ni hat :wink: .

Code:
PS C:\Scripts> get-help mkdir

NAME
    New-Item
   
SYNTAX
    New-Item [-Path] <string[]> [-ItemType <string>] [-Value <Object>] [-Force] [-Credential
    <pscredential>] [-WhatIf] [-Confirm] [-UseTransaction]  [<CommonParameters>]
   
    New-Item [[-Path] <string[]>] -Name <string> [-ItemType <string>] [-Value <Object>] [-Force]
    [-Credential <pscredential>] [-WhatIf] [-Confirm] [-UseTransaction]  [<CommonParameters>]

ALIASE
    ni
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Export-NAVApplicationObjectFile mit Serverwahl

15. Oktober 2014 15:50

Damit bei NAV 2015-Exporten der richtige Client verwendet wird, muss der Programmpfad in der Zeile mit $NAVFolder= angepasst werden.
Die andere Funktion oben dann entsprechend zur Unterscheidung in Export-NAV71ApplicationObjectFileFlexiServer umbenennen.
Code:
## NAV 2015
function Export-NAV80ApplicationObjectFileFlexiServer

{
 [CmdletBinding()]param (
 [String]$WorkingFolder,
 [String]$ExportFile,
 [String]$Server,
 [String]$Database,
 [String]$Filter )


 $LogFile = "$WorkingFolder\Log_$ExportFile"
 $ExportFile = "$WorkingFolder\$ExportFile"


 if (Test-Path "$WorkingFolder\navcommandresult.txt") {Remove-Item "$WorkingFolder\navcommandresult.txt"}
 if (test-path $ExportFile) {remove-item $ExportFile}

 $NAVFolder = '"C:\Program Files (x86)\Microsoft Dynamics NAV\80\RoleTailored Client'
 $exportfinsqlcommand = """$NAVFolder\finsql.exe"" command=exportobjects,file=$ExportFile,servername=$Server,database=$Database,Logfile=$LogFile"
 if ($Filter -ne ""){$exportfinsqlcommand = "$exportfinsqlcommand,filter=$Filter"}
 $Command = $exportfinsqlcommand
 Write-Debug $Command
 cmd /c $Command

 $ExportFileExists = Test-Path "$ExportFile"
 If (-not $ExportFileExists) {
   write-error "Error on exporting to $ExportFile. Look at the information below."
   if (Test-Path "$WorkingFolder\navcommandresult.txt"){Type "$WorkingFolder\navcommandresult.txt"}
   if (Test-Path $LogFile) {type $LogFile}
 }
 else{
   $NAVObjectFile = Get-ChildItem $ExportFile
   if ($NAVObjectFile.Length -eq 0) { Remove-Item $NAVObjectFile }
   if (Test-Path "$WorkingFolder\navcommandresult.txt") { Type "$WorkingFolder\navcommandresult.txt"}
 }
}


Auch hier natürlich über
Code:
notepad $profile

die Profildatei aufrufen und mit dieser neuen Funktion ergänzen.

Re: Export-NAVApplicationObjectFile mit Serverwahl

20. Oktober 2014 11:54

In den erweiterten Tools, die bei NAV 2015 mitkommen, wird die obige Funktion für NAV 2015 nicht mehr benötigt.
Mit diesen Tools kommt jetzt ein neues Cmdlet mit: Export-NAVApplicationObject (CommandType: Function), das derzeit sogar den MSDN-Bloggern unbekannt ist (Link) :wink: .
Mit diesem kann man sogar die unlizenzierten Objekte weglassen (-ExportTxtSkipUnlicensed).
Code:
Export-NAVApplicationObject -DatabaseName NAV800DE_RTM -Path C:\Upgrade\NAV800DEAllObjects.txt -DatabaseServer KK-NB\NAVDEMO -ExportTxtSkipUnlicensed -Filter "Version List = *MyFilter*" -Force

Für ältere Datenbanken (NAV 2013 R2) ist das Cmdlet leider nicht verwendbar, da kommt die übliche Konvertierungswarnung. Der "OK button" fehlt aber ohnehin in der PowerShell :mrgreen:.
Code:
Export-NAVApplicationObject : : [6146865] The NAV710DE_UR11 database on the KK-NB\NAVDEMO server
must be converted before you can use it with this version of the Microsoft Dynamics NAV Development
Environment.
If you convert the database, you will no longer be able to open it with older versions of Microsoft
Dynamics NAV Development Environment.
We strongly recommended that you make a database or transaction log backup in SQL Server before the
conversion.
Choose the OK button to convert the database, or choose the Cancel button to exit.

Re: Export-NAVApplicationObjectFile mit Serverwahl

20. Oktober 2014 13:13

Kowa hat geschrieben:Für ältere Datenbanken (NAV 2013 R2) ist der leider nicht verwendbar, da kommt die übliche Konvertierungswarnung. Der "OK button" fehlt aber ohnehin in der PowerShell :mrgreen:.
Code:
Export-NAVApplicationObject : : [6146865] The NAV710DE_UR11 database on the KK-NB\NAVDEMO server
must be converted before you can use it with this version of the Microsoft Dynamics NAV Development
Environment.
If you convert the database, you will no longer be able to open it with older versions of Microsoft
Dynamics NAV Development Environment.
We strongly recommended that you make a database or transaction log backup in SQL Server before the
conversion.
Choose the OK button to convert the database, or choose the Cancel button to exit.


Aha, also geht das dann doch nicht ab CU 9 NAV2013R2 (siehe PDF Seite 12)... ?
(Link)

mfg,
winfy

Re: Export-NAVApplicationObjectFile mit Serverwahl

20. Oktober 2014 13:45

winfy hat geschrieben:Aha, also geht das dann doch nicht ab CU 9 NAV2013R2 (siehe PDF Seite 12)... ?
(Link)

Das geht, aber das ist der im ersten Beitrag erwähnte Befehl ExportObjects in der normalen Kommandozeile (Development Environment Commands), der hat mit dem neuen Cmdlet für die PowerShell nichts gemein, auch wenn dieser ebenfalls dafür gedacht ist, Objekte zu exportieren. Export-NAVApplicationObject ist eine Wrapper-Funktion für ExportObjects.

Wenn man Objekte aus beiden Versionen benötigt, und das alles innerhalb der PowerShell abwicklen möchte, mit gleichartigen Mustern, die schnell variiert werden können, ist die obige Funktion Export-NAV80ApplicationObjectFileFlexiServer natürlich auch für NAV 2015 trotzdem gut zu verwenden, weil man ab dem zweiten Export praktisch alles aus dem Eingabespeicher ziehen kann und meist nur den Datenbank-, Exportdatei- und Funktionsnamen jeweils leicht anpassen muss.

Re: Export-NAVApplicationObjectFile mit Serverwahl

10. Februar 2015 16:48

Bei Paralellbetrieb von Builds in NAV 2015 (Anlass: Datenbankkonvertierung durch CU 4 für NAV 2015) benötigt man für die obige Funktion ab CU 4 eine weitere Variante, mit geändertem Clientpfad für das aktuelle Build 39663, da die älteren Builds nicht aus dieser Datenbank exportieren können.
Die Benennung von "80_39663" für den Clientordner fühte dabei bei mir zu "Das System kann den angegebeben Pfad nicht finden". Grund war eine Überlänge in dem zusammengesetzten cmd-Befehl, mit "80_4" ging es dann wieder.

Edit 22.07.15: Da gleiche Spiel für CU 8 und CU 9, diese konvertieren die Datenbank erneut und benötigen eigene Versionen (80_8,80_9). Die Datenbank aus CU 8 sollte auch nicht mit älteren Builds geöffnet werden, da diese dann ohne Rückfrage downgegraded wird.

Edit 10.09.15: Bei NAV 2013 R2 ist in CU 22 ebenfalls eine Datenbankkonvertierung.