I'm a bit of a noob to NAV development, and was unable to find a good ready-made way to get all objects that I have permission to export out into text files that could be meaningfully source-controlled, so I wrote this powershell script that attempts to export all of them and just moves on when it gets the permission error.
#### change these params to point this script at a different server or different directory ####
$serverName = "server_where_nav_db_lives"
$dbname = "name_of_your_nav_db"
$destFolder = "c:\TestNavExport"
$startTime = [System.DateTime]::Now
function doExport {
param ([string]$type, [string]$id, [string]$name, [string]$svr, [string]$db, [string]$dest)
$cleanName = $name.replace("/", "")
$filepath = "`"{0}\{1}s\{2} - {3}.txt`"" -f $dest, $type, $id, $cleanName
write-host "filepath is $filepath"
### change this value to use a different version of the dev environment
$finpath = "c:\program Files (x86)\Microsoft Dynamics NAV\71\RoleTailored Client - CU25\finsql.exe"
$args = "command=exportobjects, file=$filepath, servername=$svr, database=$db, ntauthentication=yes, logfile=`"$dest\exportlog-$type-$cleanName.txt`", filter=`"Type=$type;ID=$id`" "
Start-Process $finpath -ArgumentList $args -Wait
}
function CheckExists {
param ([string]$pth)
if (-Not [System.IO.Directory]::Exists($pth)) { md -Path $pth }
}
$qry = @"
SELECT
o.ID,
o.[Name],
o.[Type],
CASE o.[Type] WHEN 0 THEN 'Table'
WHEN 3 THEN 'Report'
WHEN 5 THEN 'CodeUnit'
WHEN 6 THEN 'XMLPort'
WHEN 7 THEN 'MenuSuite'
WHEN 8 THEN 'Page'
WHEN 9 THEN 'Query'
ELSE 'Other'
END ObjType
FROM [Object] o
WHERE o.[Type] IN (0, 3, 5, 6, 7, 8, 9)
AND o.[ID] < 150
ORDER BY o.[ID]
"@
# make sure all the necessary directories exist
CheckExists $destFolder
CheckExists "$destFolder\Tables"
CheckExists "$destFolder\CodeUnits"
CheckExists "$destFolder\Pages"
CheckExists "$destFolder\Reports"
CheckExists "$destFolder\XMLPorts"
CheckExists "$destFolder\MenuSuites"
CheckExists "$destFolder\Querys"
# query the database for all of the objects
$connection = new-object system.Data.SqlClient.SqlConnection("Server=$serverName;Database=$dbname;Trusted_Connection=True")
$connection.Open();
$cmd = $connection.CreateCommand();
$cmd.CommandText = $qry;
$cmd.Connection = $connection;
$reader = [System.Data.SqlClient.SqlDataReader]$cmd.ExecuteReader()
while ($reader.Read()) {
$cid = $reader["ID"];
$cname = $reader["Name"]
$ctype = $reader["Type"]
$cTypeName = $reader["ObjType"]
write-host "exporting $cname $cid $ctypename"
doExport $cTypeName $cid $cname $serverName $dbname $destFolder
}
$connection.Close()
$endTime = [System.DateTime]::Now
("start time {0}, end time {1}, span {2}" -f $startTime, $endTime, ($endTime - $startTime)) | out-file "$destFolder\clock.txt"
I also found this other question, which shows how to get that text out of the object metadata table. This article has sample code that looks like it could translate the blobs in the metadata table into the text. Having written the script and verified that it works, I've stuck with the script so far. As a noob, I will not be too surprised if I find a much more efficient solution soon.