# v255 helper: clean old sessions, discover the target, connect once, and show present-only CD-ROM devices.
# Run PowerShell as Administrator. Start gdr8050l_auth_v255_dynamic_iscsi_start.cmd in another console first.
param(
    [Alias('Address','Host','Portal','TargetPortalAddress')]
    [string]$PortalAddress = '192.168.0.8',
    [int]$PortalPort = 3260,
    [string]$TargetName = 'iqn.2026-06.local.mn103s:gdr8050l',
    [switch]$KeepExistingPortal,
    [switch]$KeepExistingSessions
)
$ErrorActionPreference = 'Stop'

$PortalAddress = [string]$PortalAddress
$PortalAddress = $PortalAddress.Trim()
if ($PortalAddress -match '^-+([0-9]{1,3}(\.[0-9]{1,3}){3})$') {
    $PortalAddress = $Matches[1]
    Write-Warning "PortalAddress looked like a mistyped switch; using $PortalAddress"
}
if ($PortalAddress -match '^\[(.+)\]$') { $PortalAddress = $Matches[1] }
if ([string]::IsNullOrWhiteSpace($PortalAddress)) { throw 'PortalAddress is empty.' }
if ($PortalAddress.StartsWith('-')) {
    throw "PortalAddress starts with '-'. Use '-PortalAddress 192.168.0.8' or run with no argument; do not run '-192.168.0.8'."
}

Start-Service MSiSCSI
Write-Host "Portal: $PortalAddress`:$PortalPort"
Write-Host "Target: $TargetName"
try {
    $tcpOpen = Test-NetConnection -ComputerName $PortalAddress -Port $PortalPort -InformationLevel Quiet -WarningAction SilentlyContinue
    if (-not $tcpOpen) {
        Write-Warning "TCP probe to $PortalAddress`:$PortalPort failed before iSCSI discovery. Confirm the target console is still listening and Windows Firewall allows the port."
    }
} catch {
    Write-Warning "TCP probe failed: $($_.Exception.Message)"
}

if (-not $KeepExistingSessions) {
    $sessions = @(Get-IscsiSession -ErrorAction SilentlyContinue | Where-Object { $_.TargetNodeAddress -eq $TargetName })
    if ($sessions.Count -gt 0) {
        Write-Host "Disconnecting $($sessions.Count) stale session(s) for target before fresh discovery..."
        foreach ($s in $sessions) {
            Disconnect-IscsiTarget -SessionIdentifier $s.SessionIdentifier -Confirm:$false -ErrorAction SilentlyContinue | Out-Null
        }
        Start-Sleep -Milliseconds 750
    }
}

$existing = @(Get-IscsiTargetPortal -ErrorAction SilentlyContinue | Where-Object { $_.TargetPortalAddress -eq $PortalAddress -and $_.TargetPortalPortNumber -eq $PortalPort })
if ($existing.Count -gt 0 -and -not $KeepExistingPortal) {
    Write-Host 'Removing stale portal entry before fresh SendTargets discovery...'
    Remove-IscsiTargetPortal -TargetPortalAddress $PortalAddress -TargetPortalPortNumber $PortalPort -Confirm:$false -ErrorAction SilentlyContinue
    Start-Sleep -Milliseconds 500
}

try {
    New-IscsiTargetPortal -TargetPortalAddress $PortalAddress -TargetPortalPortNumber $PortalPort -ErrorAction Stop | Out-Null
} catch {
    Write-Warning "New-IscsiTargetPortal failed: $($_.Exception.Message)"
}

Start-Sleep -Milliseconds 500
$target = Get-IscsiTarget -ErrorAction SilentlyContinue | Where-Object { $_.NodeAddress -eq $TargetName } | Select-Object -First 1
if (-not $target) {
    Write-Host 'Target was not listed on first query; retrying after a short delay...'
    Start-Sleep -Seconds 1
    $target = Get-IscsiTarget -ErrorAction SilentlyContinue | Where-Object { $_.NodeAddress -eq $TargetName } | Select-Object -First 1
}
if (-not $target) {
    Write-Host ''
    Write-Host 'Known iSCSI targets after discovery:'
    Get-IscsiTarget -ErrorAction SilentlyContinue | Format-List NodeAddress,IsConnected
    throw "Target not discovered: $TargetName"
}

Connect-IscsiTarget -NodeAddress $TargetName -TargetPortalAddress $PortalAddress -TargetPortalPortNumber $PortalPort -IsPersistent $false -ErrorAction Stop | Format-List
Write-Host ''
Write-Host 'Connected target state:'
Get-IscsiTarget | Where-Object { $_.NodeAddress -eq $TargetName } | Format-List
Write-Host ''
Write-Host 'Matching present CD-ROM PnP devices:'
Get-PnpDevice -PresentOnly -Class CDROM -ErrorAction SilentlyContinue | Where-Object { $_.InstanceId -like 'SCSI\CDROM&VEN_HL-DT-ST&PROD_DVD-ROM_GDR8050L*' } | Format-Table -AutoSize Status,Class,FriendlyName,InstanceId
Write-Host ''
Write-Host 'Win32_CDROMDrive matching devices; note that stale non-present devices can remain until removed:'
Get-CimInstance Win32_CDROMDrive | Where-Object { $_.PNPDeviceID -like 'SCSI\CDROM&VEN_HL-DT-ST&PROD_DVD-ROM_GDR8050L*' } | Format-List Drive,MediaLoaded,Name,Manufacturer,PNPDeviceID
Write-Host ''
Write-Host 'If multiple stale drive letters remain, disconnect and remove only emulator-created stale devnodes with:'
Write-Host "  .\gdr8050l_auth_v255_dynamic_iscsi_disconnect_windows_iscsi.ps1 -PortalAddress $PortalAddress -PortalPort $PortalPort -RemoveStaleCdromDevices"
