Public/ImportExport/Import-HardwareCsv.ps1

function Import-HardwareCsv {
    <#
    .SYNOPSIS
        Adds hardware to a Milestone VMS using a CSV file
 
    .DESCRIPTION
        Adds hardware to a Milestone VMS using a CSV file. The required columns include
 
        - RecordingServerName - The display name of the Recording Server where the device should be added
        - HardwareAddress - The address of the device to be added in the format "http://ip.add.re.ss"
        - HardwareName - The desired display name of the new hardware device
        - UserName - The user name on the device - typically 'root' or 'admin'
        - Password - The password for the given UserName on the device
        - GroupPath - Optional. Defines the camera group where new cameras will be placed. Default is '/New Cameras'
        - DriverNumber - Optional. Add-Hardware is much faster when you know the driver to use. Specify the driver number
            when possible, but if you leave it blank, the Recording Server will try to scan the hardware to discover the driver.
 
        When importing with the Full parameter, a separate file for each row of the CSV file is expected to be found adjascent
        to the CSV file with a name like "csvname_guid.json" where csvname is the filename of the CSV file provided in -Path,
        and guid is an ID matching the ConfigurationId column from the CSV file.
 
        This command will make an effort to match all settings present in the adjascent JSON files. However, some settings are
        not available through Configuration API, and advanced settings like secondary streams, or events are not included.
 
    .PARAMETER Path
        Path to the location of the CSV file from where the hardware information will be imported
 
    .PARAMETER Full
        Perform a deep copy of the configuration using the adjascent JSON files generated by the Export-HardwareToCsv command.
 
    .PARAMETER RecordingServer
        Override the Recording Servers designated in the CSV file and add all hardware in the CSV file to this Recording
        Server instead.
 
    .EXAMPLE
        Connect-ManagementServer -Server localhost
        Import-HardwareFromCsv -Path C:\hardware.csv
 
        Logs into the local Management Server as the current Windows user and imports hardware defined in C:\hardware.csv
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory, Position = 1)]
        [string]
        $Path,
        [Parameter()]
        [switch]
        $Full,
        [Parameter()]
        [VideoOS.Platform.ConfigurationItems.RecordingServer]
        $RecordingServer
    )

    process {
        $exportDirectory = Split-Path -Path $Path -Parent
        $rows = @(Import-Csv -Path $Path)
        $recorderMap = @{}
        for ($i = 0; $i -lt $rows.Count; $i++) {
            try {
                Write-Verbose "Processing row $($i + 1) of $($rows.Count)"
                $recorder = if($null -ne $RecordingServer) { $RecordingServer } else {
                    if ($recorderMap.ContainsKey($rows[$i].RecordingServerName)) {
                        $recorderMap[$rows[$i].RecordingServerName]
                    } else {
                        $rec = Get-RecordingServer -Name $rows[$i].RecordingServerName
                        $recorderMap.Add($rec.Name, $rec)
                        $rec
                    }
                }
                Write-Verbose "Adding $($rows[$i].HardwareAddress) to $($recorder.HostName)"

                $hardwareArgs = @{
                    Name = $rows[$i].HardwareName
                    Address = $rows[$i].HardwareAddress
                    UserName = $rows[$i].UserName
                    Password = $rows[$i].Password
                    GroupPath = if ($rows[$i].GroupPath) { $rows[$i].GroupPath } else { '/New Cameras' }
                }

                # Only add DriverId property if DriverNumber is present in this row
                # Rows where DriverNumber is not present will result in the Recording
                # Server scanning to discover the right driver to use.
                if ($rows[$i].DriverNumber) {
                    $hardwareArgs.Add('DriverId', $rows[$i].DriverNumber)
                }

                $hw = $null
                try {
                    $hw = $recorder | Add-Hardware @hardwareArgs -ErrorAction Stop
                    Write-Verbose "Successfully added $($hw.Name) with ID $($hw.Id)"
                    if ($Full -and $null -ne $hw) {
                        $configId = $rows[$i].ConfigurationId
                        $configPath = Join-Path -Path $exportDirectory -ChildPath "$([System.IO.Path]::GetFileNameWithoutExtension($Path))_$configId.json"
                        Get-Content -Path $configPath -Raw | ConvertFrom-Json |
                            Copy-ConfigurationItem -DestinationItem ($hw | Get-ConfigurationItem -Recurse -Sort) -Verbose:$VerbosePreference
                    }
                    Write-Output $hw
                } catch {
                    Write-Error $_
                }
            } catch {
                Write-Error $_
            }
        }
    }
}