# Automation Workflows
The below PowerShell script automates the process of importing layers into the Civillo. It handles authentication, interacts with the Civillo API to select organizations and projects, reads layer data from a CSV file, creates layers in the specified project, and assigns them to directories. The script provides user-friendly menus for organization and project selection and handles various aspects of the import process.
The below script requires PowerShell version 7.0 or above. To install PowerShell 7 please watch this installation video. (opens new window)
Users can copy, edit and save this script. To review how to use the script, you can run:
PS > get-help .\{name-of-script}.ps1
or
PS > get-help .\{name-of-script}.ps1 -Full
And can be run using the following parameters (at a minimum)
PS > .\{name-of-script}.ps1 \
-civilloKey "{YOUR-CIVILLO-KEY}" \
-civilloSecret "{YOUR-CIVILLO-SECRET}" \
-inputcsv "PATH\TO\file.csv"
or
PS > .\{name-of-script}.ps1 \
-civilloKey "{YOUR-CIVILLO-KEY}" \
-civilloSecret "{YOUR-CIVILLO-SECRET}" \
-inputCsv "PATH\TO\file.csv" \
-organization "{organization nickname}"
-projectId "{Project ID}"
- The organization nickname can be retrieved using the Organizations' (opens new window) endpoint.
- The Project ID can be retrieved using the Projects' (opens new window) endpoint.
An example CSV file can be downloaded from here.
# PowerShell script
<#
.SYNOPSIS
Imports local CAD, IFC and 12d files to a Civillo project, and assigns the layer to a directory.
.DESCRIPTION
Imports local CAD, IFC and 12d files to a Civillo project, and assigns the layer to a directory.
.PARAMETER civilloKey
Civillo Key. Log into Civillo and navigate to your profile (https://app.civillo.com/i/user/profile).
At the bottom of the profile page, you can generate a new key or copy an existing key.
.PARAMETER civilloSecret
Civillo Secret. Log into Civillo and navigate to your profile (https://app.civillo.com/i/user/profile).
At the bottom of the profile page, you can generate a new key with secret, or use your previously saved secret.
.PARAMETER inputCsv
Path to input CSV file which contains the following columns:
File,LayerName,Description,Directory,srid,units,makeGlobal,convert3dFaces,convert3dFacesToTerrain
.PARAMETER organization
Civillo organization nickname.
This can be found in the URL of your civillo project.
E.g: https://app.civillo.com/{ORGANIZATION-NAME}/project/{PROJECT-ID}/?L9;V2#17/-37.75085/144.997355
.PARAMETER projectId
Civillo project ID of the organization.
This can be found in the URL of your civillo project.
E.g: https://app.civillo.com/{ORGANIZATION-NAME}/project/{PROJECT-ID}/?L9;V2#17/-37.75085/144.997355
.EXAMPLE
PS> .\civillo-import-csv.ps1 -civilloKey "{YOUR-CIVILLO-KEY}" -civilloSecret "{YOUR-CIVILLO-SECRET}" -inputCsv "{PATH/TO/CSV/FILE}"
.EXAMPLE
PS> .\civillo-import-csv.ps1 -civilloKey "{YOUR-CIVILLO-KEY}" -civilloSecret "{YOUR-CIVILLO-SECRET}" -inputCsv "{PATH/TO/CSV/FILE}" -organization "{ORGANIZATION ABBREVIATION}"
.EXAMPLE
PS> .\civillo-import-csv.ps1 -civilloKey "{YOUR-CIVILLO-KEY}" -civilloSecret "{YOUR-CIVILLO-SECRET}" -inputCsv "{PATH/TO/CSV/FILE}" -organization "{ORGANIZATION ABBREVIATION}" -projectId {PROJECT-ID}
#>
#Requires -Version 7.0
param (
[Parameter(Position=1, Mandatory=$true)]
[string]$civilloKey,
[Parameter(Position=2, Mandatory=$true)]
[string]$civilloSecret,
[Parameter(Position=3, Mandatory=$true)]
[string]$inputCsv,
[Parameter(Position=4, Mandatory=$false)]
[string]$organization,
[Parameter(Position=5, Mandatory=$false)]
[Int16]$projectId
)
Add-Type -AssemblyName System.Windows.Forms
# Functions
Function DrawMenu {
## Support function to the Menu function below
param ($menuItems, $menuPosition, $menuTitel)
$fcolor = $host.UI.RawUI.ForegroundColor
$bcolor = $host.UI.RawUI.BackgroundColor
$l = $menuItems.length + 1
cls
Write-Host "$menuTitel" -fore $fcolor -back $bcolor
Write-Host ""
Write-debug "L: $l MenuItems: $menuItems MenuPosition: $menuposition"
for ($i = 0; $i -le $l;$i++) {
Write-Host " " -NoNewLine
if ($i -eq $menuPosition) {
Write-Host "$($menuItems[$i])" -fore $bcolor -back $fcolor
} else {
Write-Host "$($menuItems[$i])" -fore $fcolor -back $bcolor
}
}
}
Function Menu {
## Generate a small "DOS-like" menu.
## Choose a menuitem using up and down arrows, select by pressing ENTER
param ([array]$menuItems, $menuTitel = "MENU")
$vkeycode = 0
$pos = 0
DrawMenu $menuItems $pos $menuTitel
While ($vkeycode -ne 13) {
$press = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown")
$vkeycode = $press.virtualkeycode
Write-host "$($press.character)" -NoNewLine
If ($vkeycode -eq 38) {$pos--}
If ($vkeycode -eq 40) {$pos++}
if ($pos -lt 0) {$pos = $menuItems.length -1}
if ($pos -ge $menuItems.length) {$pos = 0}
DrawMenu $menuItems $pos $menuTitel
}
Write-Output $($menuItems[$pos])
}
Function Invoke-OpenFileDialog {
## Open a file dialog window to select CSV.
Param (
[Parameter(Mandatory=$true, Position=0)] [string] $DialogTitle,
[Parameter(Mandatory=$true, Position=1)] [string] $InitialDirectory,
[Parameter(Mandatory=$true, Position=2)] [string] $Filter,
[Parameter(Mandatory=$true, Position=3)] [boolean] $TopMost
)
if ($InitialDirectory -ne "") {
if (!(Test-Path -LiteralPath $InitialDirectory -PathType Container)) {
$InitialDirectory = ([System.IO.FileInfo]$InitialDirectory).DirectoryName
}
}
# Create a streaming image by streaming the base64 string to a bitmap stream source.
$IconBase64 = "iVBORw0KGgoAAAANSUhEUgAAABsAAAAgCAYAAADjaQM7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAATQSURBVEhL7ZZ/TBxFFMd3Znfv9g6O3xypCVRSaFoCtS2QFkmhVFEoqRCLFStJTUHapPWPGk3xL1NtY2JMNRoTU4SmSI8fVUtTQgsmQikmgFZNCRxi0wrFMx7g3XFHub3d2fXNsSAgAv2hiUk/yWR33pu335k3b2eXecj/DqRd75uG+nqeZdlVDodDCA0LW8ViPB4TE3Nzc3LyHW3IvYmdrakJlmU5HloiQigJTFEqw8gcyw7JhFwLCQ4e4jhuOL+gwDEdMc2yYjabjW1va1sjimKqJElbMcaZhJBIcE3CSqwsx12FVbSDv/flsrKp6ajFWVSspaXF9JvNtsnn8+XAzAvg4eupHR5+Ay5f6vT6Vr1e31NUVOSm9pUyK/a73Y4vNTdvUQjZB+nJAYHVqqoyIObgeb6O1+lO5+Tmfh9lNhMt5K7xi1VVVpaBwCEQ2EAF/A6EZI7nTxoMhveKi4tH/cb7BFVUVJTLkvTOjMgMsJpXYQ/e17oPBAxpy1MVRev+haIoa4eGh7HWfSAgS031Lo9n8oIkE8jc/HqByvsRCuG8TqfrhHb9uT17xjTXPYFeueqOXne7I1s/8ctRH2HWavZ50ElAs0MbRBj3YYR69YIwBns8ABXqDQ8P/+Pbnh7H5pQUvDM3VwGbrIXOAx1rsgo/M0GHzWTS9pitSZSwoVwiasrCPVwInQCMIbB6Fe6psBNEMGRA9Hq9fdRHh4GN7j+PWfZd1H3ZYhqSzQe+kOIzbD5mKDmAfJw+2hQxIeJ9korzQTNyOeG50LF0InOhfUEQtvmtljNVu0WVTaoSMsy8quwnCFdGmgIsu8XuYTwxkuER1V0SYbaB5CN3IzwDHF234uLjN8xOoerTigpVkZ2XQp8eGZPUkxyjYgWhaxLmPl8dJFzJFPt/DXUPJnimyHbY20yiMokgHKiFLwkU2ZGS0tIPZsVq6xt0HpezGxFx8IeIHR/1ysa3WIVkUR9H04KYnzDHfS2y/MUEvdyX4WrDZNKRICp8FmHgvFSYdSBuWrhy2MOOLWlpTyQlJsrzkvtZdXW0x+Pp5JDi0gebSyzC4+mKKB7zKWoQ9dPBtEE1TrAY9TIs167yfHuS3jeY5v5GUe844r0EbxUJTvNJcrjRaLwRaDK9XlhYaJ+Jn8e5hoZkp9PZI8uSGGJkDzdGFba43O7j8B6+BKnzQ4Po7bSw3+KEKuiHT8x3E4i9EhMc0FX/VKiNeubyNzFKfV1dtsvlaoLzUqdjkSU6gi8vwQVBm2T3h15Z2SGB0qKBABU3C+ze2mdjazXTLIseR88XFX0VEhLyDLweXh9R994ala+fGD+X/UbMzTxDYMBOA4u76UMX1iXtwwP7eQ6dn7bM558m6AdWmDo+Pk5nuIb2MUbWQF45HrMxvfHE7agszud9UyRKKk0vFTKyiIkUcN6ZgthmOn4hS4pRKk6dioNDuRVOiFjapy8onAp9gZz8duTGjIufjIQ9OTE59SKImaIDuJrT+Y9a/IGLsKwY5UJjY5zdbrfAb0GqZvKLQlVag/TKkRf2H2rRzEuyok8I/LjcgH+N7fDOtGom/7FEFGW9lzEImmlZVrSyGawDA1xnR8drcFsKbRLSe/TAwYOX/c5/i66uLsOA1arTug/5L2GYPwFXOg3LzbJqMQAAAABJRU5ErkJggg=="
$iconBytes = [Convert]::FromBase64String($IconBase64)
$stream = New-Object IO.MemoryStream($iconBytes, 0, $iconBytes.Length)
$stream.Write($iconBytes, 0, $iconBytes.Length)
# Create a new form to hold the object and set it properties for the main
# OpenFileDialog form.
$OpenFileDialogForm = New-Object System.Windows.Forms.Form
$OpenFileDialogForm.Icon = [System.Drawing.Icon]::FromHandle((New-Object System.Drawing.Bitmap -Argument $stream).GetHIcon())
$OpenFileDialogForm.TopMost = $TopMost
# Set the properties of the main OpenFileDialog along with using the
# OpenFileDialogForm properties from above.
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.Filter = $Filter
$OpenFileDialog.InitialDirectory = $InitialDirectory
$OpenFileDialog.Title = $DialogTitle
$userClicked = $OpenFileDialog.ShowDialog($OpenFileDialogForm)
$OpenFileDialog.Dispose()
if ($userClicked -eq 'OK') { return $OpenFileDialog.FileName } else { return "" }
}
$civilloUriBase = "https://app.civillo.com/api/v1"
## Check for the Civillo Key parameter for this script;
if ($null -eq $civilloKey) {
$civilloKey = read-host -Prompt "Enter Civillo Key: "
}
## Check for the Civillo Secret parameter for this script;
if ($null -eq $civilloSecret) {
$civilloSecret = read-host -Prompt "Enter Civillo Secret: "
}
## Encode the Civillo Key and Secret into a Base64 string
$encoded = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$($civilloKey):$($civilloSecret)"))
## Set the header authorization for the API requests
$headers = @{
'Authorization' = "Bearer $($encoded)"
}
## Validate the CSV input
if ($null -eq $inputCsv) {
$dialogTitle = 'Select a CSV file'
$initialDirectory = (New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
$dialogFilter = 'CSV (*.csv)|*.csv'
$inputCsv = Invoke-OpenFileDialog -DialogTitle $dialogTitle -InitialDirectory $initialDirectory -Filter $dialogFilter -TopMost $true
}
if ($inputCsv -eq "")
{
Write-Host "No CSV file supplied. Exiting." -ForegroundColor Yellow
exit
}
$fileExists = Test-Path -Path $inputCsv -PathType Leaf
if ($fileExists -eq $false)
{
Write-Host "No CSV file located at $($inputCsv). Exiting." -ForegroundColor Yellow
exit
}
## Validate the input CSV has the correct headers
$csvHeaders = Get-Content -Path $inputCsv | Select-Object -First 1
$expectedHeaders = "file,layername,description,directory,srid,units,makeglobal,convert3dfaces,convert3dfacestoterrain"
if ($csvHeaders.ToLower() -ne $expectedHeaders) {
Write-Host "Inconsistent CSV file headers. This script is expecting these column names in the input CSV: " -ForegroundColor Yellow
Write-Host "---------------------------------------------------------------------------------------------------------"
Write-Host "File, LayerName, Description, Directory, SRID, Units, MakeGlobal, Convert3dFaces, Convert3dFacesToTerrain"
Write-Host "---------------------------------------------------------------------------------------------------------"
Write-Host "Exiting." -ForegroundColor Yellow
exit
}
$csv = Import-csv -path $inputCsv
## Processing Step 1. Select an Organization
if ([string]::IsNullOrEmpty($organization)) {
$uri = "$($civilloUriBase)/applications"
Try {
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit
}
If ($response.Count -eq 1) {
$organization = $response[0].nickname
}
ElseIf ($response.Count -lt 6) {
$organizationArray = @()
foreach($org in $response) {
$organizationArray += $org.name
}
$selection = Menu $organizationArray "Please choose an organization:"
foreach($org in $response) {
if($org.name -eq $selection){
$organization = $org.nickname
}
}
}
Else {
$organizationFilter = Read-Host -Prompt "Set an organization filter"
$organizationArray = @()
foreach($org in $response) {
if ($org.name -Match $organizationFilter) {
$organizationArray += $org.name
}
}
$selection = Menu $organizationArray "Please choose an organization:"
foreach($org in $response) {
if($org.name -eq $selection){
$organization = $org.nickname
}
}
}
}
Start-Sleep -Seconds 1
## Processing Step 2. Select an organization's project
$uri = "$($civilloUriBase)/$($organization)/projects"
Try {
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit
}
$projectsArray = @()
foreach($app in $response) {
$projectsArray += $app.name
}
if (-not($response.id -contains $projectId)) {
$projectId = $null
}
if ([string]::IsNullOrEmpty($projectId) -Or $projectId -eq 0) {
$selection = Menu $projectsArray "Please choose a project:"
$projectId = 1;
Write-Host "Using $selection project"
foreach($app in $response) {
if($app.name -eq $selection){
$projectId = $app.id
}
}
}
## Processing Step 3. Select a list of valid SRS inputs for Civillo
Start-Sleep -Seconds 1
$uri = "$($civilloUriBase)/global/reference_systems"
Try {
$projections = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
}
## Processing Step 4. Fetch the current list of layers in the project
Start-Sleep -Seconds 1
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layers"
Try {
$projectLayers = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
}
## Processing Step 5. Loop over the CSV rows.
foreach($line in $csv)
{
## Processing Step 5.1. Validate the input file
$outputFile = Split-Path $line.file -leaf
$fileExists = Test-Path -Path $line.file -PathType Leaf
if ($fileExists -eq $false)
{
Write-Host "$($outputFile) not located at $($line.file). Skipping." -ForegroundColor Yellow
continue
}
## Processing Step 5.2. This script will only process CAD. IFC and 12d files
$knownExtensionsForScript = @(".dgn", ".dxf", ".dwg", ".ifc", ".12da", ".12daz")
$fileExtension = [System.IO.Path]::GetExtension($line.file.ToLower())
if ($knownExtensionsForScript.IndexOf($fileExtension) -eq -1) {
Write-Host "$($outputFile) will not be processes by this script. Only dgn, dxf, dwg, ifc, 12da and 12daz are accepted. Skipping." -ForegroundColor Yellow
continue
}
## Processing Step 5.3. Validate the CSV SRID value
[int]$srid = -1
foreach($projection in $projections) {
if ($projection.name -Contains $line.srid ) {
$srid = $projection.value
}
}
if ($srid -eq -1) {
$defaultFilter = "GDA2020"
# Using the Civillo projections, select the actual SRS.
Write-Host "$($line.srid) not found as a Civillo projection. Please select a projection" -ForegroundColor Yellow
[string]$projectionFilter = Read-Host -Prompt "Set a SRS filter [$($defaultFilter)]"
$projectionFilter = ($defaultFilter,$projectionFilter)[[bool]$projectionFilter]
$projectionSeparatedList = @()
foreach($projection in $projections) {
if ($projection.name -Match $projectionFilter) {
$projectionSeparatedList += $projection.name
}
}
$sridName = Menu $projectionSeparatedList "Select SRS for file $($outputFile):"
foreach($projection in $projections) {
if ($projection.name -Contains $sridName ) {
$srid = $projection.value
}
}
}
## Processing Step 5.4. Validate the Units
$unitsEnum = @("m", "mm")
$units = $line.units.ToLower()
if ($unitsEnum.IndexOf($units) -eq -1) {
$units = Menu $unitsEnum "Please choose a valid unit for the file $($outputFile):"
}
$trueFalseEnum = @("true", "false")
## Processing Step 5.5. Validate makeGlobal
$makeGlobal = $line.makeglobal.ToLower()
if ($trueFalseEnum.IndexOf($makeGlobal) -eq -1) {
$makeGlobal = Menu $trueFalseEnum "Please choose a valid `"Make Global`" for the file $($outputFile):"
}
## Processing Step 5.5. Validate convert3dFaces
$convert3dFaces = $line.convert3dFaces.ToLower()
if ($trueFalseEnum.IndexOf($convert3dFaces) -eq -1) {
$convert3dFaces = Menu $trueFalseEnum "Please choose a valid `"Convert 3D Faces`" for the file $($outputFile):"
}
## Processing Step 5.5. Validate convert3dFacesToTerrain
$convert3dFacesToTerrain = $line.convert3dFacesToTerrain.ToLower()
if ($trueFalseEnum.IndexOf($convert3dFaces) -eq -1) {
$convert3dFacesToTerrain = Menu $trueFalseEnum "Please choose a valid `"Convert 3D Faces to Terrain`" for the file $($outputFile):"
}
Write-Host "Processing $($outputFile)" -ForegroundColor green
[int64]$lastModifiedDate = Get-Date -Date ((Get-Item $line.file).LastWriteTime) -UFormat %s
$lastModifiedDate = $lastModifiedDate * 1000
[int]$mode = 0
[int]$replaceLayerId = 0
#Does the layer already exist by name?
$fileExistsInProject = $false
foreach($layer in $projectLayers) {
if ($layer.name.Trim() -eq $line.layername.Trim()) {
$mode = 1
$replaceLayerId = $layer.layerId
Start-Sleep -Seconds 1
# Check to see if last revision fileLastModified matches our $lastModifiedDate
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layers/$($layer.layerId)"
Try{
$layerMetadata = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
}
if ($layerMetadata) {
$lastRevisionModifiedDate = $layerMetadata.revisions[0].source.fileLastModified
if ($lastRevisionModifiedDate -eq $lastModifiedDate) {
Write-Host "$($outputFile) version currently loaded to the `"$selection`" project. Skipping." -ForegroundColor Yellow
$fileExistsInProject = $true
}
}
}
}
if ($fileExistsInProject) {
continue
}
## Processing Step 5.6. Create the body JSON as part of the layer create POST
$body = @{"mode"="$($mode)"
"fileNames"=@("$($outputFile)")
"fileLastModifieds"=@($($lastModifiedDate))
"title"="$($line.layername)"
"permitSelf"="true"
"makeGlobal"="$($makeGlobal)"
"makeOnByDefault"="false"
"srid"=$($srid)
"description"="$($line.description)"
"units"="$($units)"
"convert3dFaces"="$($convert3dFaces)"
"convert3dFacesToTerrain"="$($convert3dFacesToTerrain)"
} | ConvertTo-Json
if ($mode -eq 1) {
$body = @{"mode"="$($mode)"
"fileNames"=@("$($outputFile)")
"replaceLayerId"=$replaceLayerId
"fileLastModifieds"=@($($lastModifiedDate))
"title"="$($line.layername)"
"permitSelf"="true"
"makeGlobal"="$($makeGlobal)"
"makeOnByDefault"="false"
"srid"=$($srid)
"description"="$($line.description)"
"units"="$($units)"
"convert3dFaces"="$($convert3dFaces)"
"convert3dFacesToTerrain"="$($convert3dFacesToTerrain)"
} | ConvertTo-Json
}
## Processing Step 5.7. Make POST preflight request to generate Civillo Job
Start-Sleep -Seconds 1
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layers"
Try {
$preflight = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $body -ContentType "application/json"
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
}
Start-Sleep -Seconds 1
## Processing Step 5.8. Upload the file to Civillo processPath
# Construct the URL with query parameters
$queryParams = @{
'token' = $preflight.token
'application' = $preflight.application
'jobID' = $preflight.job
}
$queryString = ($queryParams.GetEnumerator() | ForEach-Object { $_.Key + '=' + [System.Uri]::EscapeDataString($_.Value) }) -join '&'
$requestUri = $preflight.processPath + '?' + $queryString
Try {
$Form = @{file=Get-Item -Path $line.File}
$response = Invoke-RestMethod $requestUri -Method 'POST' -Form $Form
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message
}
## Processing Step 5.9. Request the progress of the Job every 30 seconds
Start-Sleep -Seconds 1
$completeResponse = $false
$errorResponse = ""
$counter = 1
do
{
$counter++
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layers/processing?jobId=$($preflight.job)"
$processing = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ContentType "application/json"
$completeResponse = $processing.complete
$errorResponse = $processing.error
if ($errorResponse) {
Write-Host "Error: " $description -ForegroundColor Red
break
}
Write-Progress -Activity ">" -Status "$($processing.status):" -PercentComplete $processing.progress
Start-Sleep -Seconds 30
if ($counter -gt 50) {
Write-Host "Processing $($outputFile) longer than 25 minutes. Aboring watch" -ForegroundColor Red
}
} while ($completeResponse -eq $false)
Write-Progress -Completed -Activity "Completed"
}
# Refresh the list of layers
Start-Sleep -Seconds 1
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layers"
Try {
$projectLayers = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -contenttype 'application/json'
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit
}
## Processing Step 6. Assign Layers to their directories
foreach($line in $csv)
{
$outputFile = Split-Path $line.file -leaf
foreach($layer in $projectLayers) {
if ($layer.name -eq $line.layername) {
Start-Sleep -Seconds 1
$uri = "$($civilloUriBase)/$($organization)/projects/$($projectId)/layer-directory"
Try {
$body = @{"layerId"=$layer.layerId
"path"="$($line.directory)"
} | ConvertTo-Json
Invoke-RestMethod -Uri $uri -Headers $headers -Method Put -Body $body -contenttype 'application/json'
Write-Host "$($outputFile) added to directory `"$($line.directory)`"." -ForegroundColor Green
}
Catch {
Write-Host $_.ErrorDetails -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
exit
}
}
}
}
Write-Host "Finished layer import." -ForegroundColor Green
exit