Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
309 changes: 309 additions & 0 deletions Scripts/Drive-reconnection/JFC/Invoke-DriveMapping.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
<#
.SYNOPSIS
Maps persistent network drives for JFC locations based on machine site code.

.DESCRIPTION
Detects the machine's site code from the computer name, looks up the corresponding
UserServer and GroupServer values, and maps persistent network drives (U:, W:, S:).
Supports all 30 JFC locations with special handling for IP-based servers and custom
share configurations.

.PARAMETER ComputerName
The computer name to extract site code from. Defaults to the local machine name.
Used primarily for testing different location scenarios.

.PARAMETER Verbose
Enable detailed output for debugging drive mapping operations.

.EXAMPLE
.\Invoke-DriveMapping.ps1
Maps drives for the local machine based on its computer name.

.EXAMPLE
.\Invoke-DriveMapping.ps1 -ComputerName "JFCS6ACT01" -Verbose
Maps drives for Kansas City location (JFC) with verbose output.

.EXAMPLE
.\Invoke-DriveMapping.ps1 -ComputerName "JOHS8ACT01" -Verbose
Maps drives for Ohio location (JOH) with verbose output.

.NOTES
Author: Copilot
Version: 1.0
Date: 2026-01-30

Special Cases:
- Terminal Servers (TRM, ACT, ACP suffix): Skipped
- JPMS2SAG (PMAI Sage): Skipped
- IP-based servers (JOH: 10.70.1.1, JPH: 10.30.1.1): Use IP instead of DNS
- Duplicate handlers: JFH/JHI, JPN/JPS/JPM, JOR/JMI, JDL/JHT, JWM/JHO

.LINK
https://github.com/J-MaFf/PowerShellScripts/issues/[ISSUE_NUMBER]
#>

[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $false)]
[string]$ComputerName = $env:COMPUTERNAME
)

# ============================================================================
# CONFIGURATION: JFC Site Mappings
# ============================================================================
$SiteConfig = @{
'IDC' = @{ UserServer = 'IDCS6BDC01'; GroupServer = 'IDCS6BDC01'; GroupShare = 'Groups' }
'JAT' = @{ UserServer = 'JATS2BDC02'; GroupServer = 'JATS2BDC02'; GroupShare = 'Groups' }
'JBO' = @{ UserServer = 'JBOS2BDC01'; GroupServer = 'JBOS2BDC01'; GroupShare = 'Groups'; SShare = '\\10.80.1.1\Groups' }
'JBR' = @{ UserServer = 'JBRS2BDC01'; GroupServer = 'JBRS2BDC01'; GroupShare = 'Groups' }
'JBT' = @{ UserServer = 'JBTS2BDC02'; GroupServer = 'JBTS2BDC02'; GroupShare = 'Groups' }
'JCH' = @{ UserServer = 'JCHS9BDC02'; GroupServer = 'JCHS9BDC02'; GroupShare = 'Groups' }
'JDE' = @{ UserServer = 'JDES2BDC02'; GroupServer = 'JDES2BDC02'; GroupShare = 'Groups' }
'JDL' = @{ UserServer = 'JHTS9BDC01'; GroupServer = 'JHTS9BDC01'; GroupShare = 'JDL_groups'; SShare = '\\10.50.1.1\Groups' }
'JFC' = @{ UserServer = 'JFCS8BDC01'; GroupServer = 'JFCS8BDC01'; GroupShare = 'Groups' }
'JFH' = @{ UserServer = 'JHIS2BDC02'; GroupServer = 'JHIS2BDC02'; GroupShare = 'Groups' }
'JHI' = @{ UserServer = 'JHIS2BDC02'; GroupServer = 'JHIS2BDC02'; GroupShare = 'Groups' }
'JHO' = @{ UserServer = 'JHOS2BDC01'; GroupServer = 'JHOS2BDC01'; GroupShare = 'Groups' }
'JHP' = @{ UserServer = '10.30.1.1'; GroupServer = '10.30.1.1'; GroupShare = 'Groups_JPH' }
'JHT' = @{ UserServer = 'JHTS9BDC01'; GroupServer = 'JHTS9BDC01'; GroupShare = 'Groups' }
'JLA' = @{ UserServer = 'JLAS2BDC01'; GroupServer = 'JLAS2BDC01'; GroupShare = 'Groups' }
'JLV' = @{ UserServer = 'JLVS2BDC01'; GroupServer = 'JLVS2BDC01'; GroupShare = 'Groups' }
'JMI' = @{ UserServer = 'JMIS2BDC01'; GroupServer = 'JMIS2BDC01'; GroupShare = 'Groups' }
'JMX' = @{ UserServer = 'JMXS6BDC01'; GroupServer = 'JMXS6BDC01'; GroupShare = 'Groups' }
'JNY' = @{ UserServer = 'JNYS6BDC01'; GroupServer = 'JNYS6BDC01'; GroupShare = 'Groups' }
'JOH' = @{ UserServer = '10.70.1.1'; GroupServer = '10.70.1.1'; GroupShare = 'JOH_groups'; SShare = '\\10.70.1.1\Groups' }
'JOR' = @{ UserServer = 'JMIS2BDC01'; GroupServer = 'JMIS2BDC01'; GroupShare = 'Groups' }
'JPH' = @{ UserServer = '10.30.1.1'; GroupServer = '10.30.1.1'; GroupShare = 'Groups_JPH' }
'JPM' = @{ UserServer = 'JPMS6BDC01'; GroupServer = 'JPMS6BDC01'; GroupShare = 'Groups' }
'JPN' = @{ UserServer = 'JPMS6BDC01'; GroupServer = 'JPMS6BDC01'; GroupShare = 'Groups' }
'JPS' = @{ UserServer = 'JPMS6BDC01'; GroupServer = 'JPMS6BDC01'; GroupShare = 'Groups' }
'JPV' = @{ UserServer = 'JPVS2BDC01'; GroupServer = 'JPVS2BDC01'; GroupShare = 'Groups' }
'JSA' = @{ UserServer = 'JSFS9BDC01'; GroupServer = 'JSFS9BDC01'; GroupShare = 'Groups' }
'JSD' = @{ UserServer = 'JSDS9BDC01'; GroupServer = 'JSDS9BDC01'; GroupShare = 'Groups' }
'JSE' = @{ UserServer = 'JSES9BDC01'; GroupServer = 'JSES9BDC01'; GroupShare = 'Groups' }
'JSF' = @{ UserServer = 'JSFS9BDC01'; GroupServer = 'JSFS9BDC01'; GroupShare = 'Groups' }
}

# ============================================================================
# FUNCTION: Extract Site Code from Computer Name
# ============================================================================
function Get-SiteCode {
param([string]$ComputerName)

Write-Verbose "[Get-SiteCode] Extracting site code from computer name: $ComputerName"

# Special case: JWM computers map to JHO
if ($ComputerName -match '^JWM') {
Write-Verbose "[Get-SiteCode] JWM computer detected; mapping to JHO"
return 'JHO'
}

# Extract first 3 characters as site code
if ($ComputerName.Length -ge 3) {
$siteCode = $ComputerName.Substring(0, 3)
Write-Verbose "[Get-SiteCode] Site code extracted: $siteCode"
return $siteCode
}
else {
Write-Error "[Get-SiteCode] Computer name too short to extract site code: $ComputerName"
return $null
}
}

# ============================================================================
# FUNCTION: Check for Terminal Server
# ============================================================================
function Test-TerminalServer {
param([string]$ComputerName)

Write-Verbose "[Test-TerminalServer] Checking if computer is terminal server: $ComputerName"

# Check terminal server suffixes from original batch logic: %computername:~5,3%
# This extracts characters at position 5-7 (0-indexed)
if ($ComputerName.Length -ge 8) {
$suffix = $ComputerName.Substring(5, 3)
Write-Verbose "[Test-TerminalServer] Checking position 5-7: $suffix"

if ($suffix -match '^(TRM|ACT|ACP)') {
Write-Verbose "[Test-TerminalServer] Terminal server detected (suffix: TRM/ACT/ACP)"
return $true
}
}

# Check for PMAI Sage
if ($ComputerName -match '^JPMS2SAG') {
Write-Verbose "[Test-TerminalServer] PMAI Sage server detected"
return $true
}

Write-Verbose "[Test-TerminalServer] Not a terminal server"
return $false
}

# ============================================================================
# FUNCTION: Disconnect Drive
# ============================================================================
function Disconnect-MappedDrive {
param(
[string]$DriveLetter,
[bool]$Force = $true
)

Write-Verbose "[Disconnect-MappedDrive] Checking drive: $DriveLetter"

try {
$drive = Get-PSDrive -Name $DriveLetter -ErrorAction SilentlyContinue

if ($drive) {
Write-Verbose "[Disconnect-MappedDrive] Drive $DriveLetter is currently mapped; disconnecting..."

if ($Force) {
net use $DriveLetter /delete /yes 2>&1 | ForEach-Object {
Write-Verbose "[Disconnect-MappedDrive] $_ "
}
}
else {
net use $DriveLetter /delete 2>&1 | ForEach-Object {
Write-Verbose "[Disconnect-MappedDrive] $_ "
}
}

Write-Verbose "[Disconnect-MappedDrive] Successfully disconnected $DriveLetter"
return $true
}
else {
Write-Verbose "[Disconnect-MappedDrive] Drive $DriveLetter is not mapped"
return $true
}
}
catch {
Write-Verbose "[Disconnect-MappedDrive] Error disconnecting $DriveLetter : $_"
return $false
}
}

# ============================================================================
# FUNCTION: Connect Network Drive
# ============================================================================
function Connect-NetworkDrive {
param(
[string]$DriveLetter,
[string]$UNCPath,
[bool]$Persist = $true
)

Write-Verbose "[Connect-NetworkDrive] Mapping $DriveLetter to $UNCPath (Persist: $Persist)"

try {
$persistFlag = if ($Persist) { '/persistent:yes' } else { '/persistent:no' }
$output = net use $DriveLetter $UNCPath $persistFlag 2>&1

if ($LASTEXITCODE -eq 0) {
Write-Verbose "[Connect-NetworkDrive] Successfully mapped $DriveLetter to $UNCPath"
return $true
}
else {
Write-Error "[Connect-NetworkDrive] Failed to map $DriveLetter to $UNCPath. Error: $($output -join ' ')"
return $false
}
}
catch {
Write-Error "[Connect-NetworkDrive] Exception mapping $DriveLetter to $UNCPath : $_"
return $false
}
}

# ============================================================================
# MAIN SCRIPT
# ============================================================================

# Only run main logic if script is invoked directly (not dot-sourced for testing)
if ($MyInvocation.InvocationName -eq '.') {
# Dot-sourced - don't run main logic
Write-Verbose "[Main] Script sourced; functions available for testing"
}
else {
# Script invoked directly - run main logic

Write-Verbose "[Main] Starting drive mapping script for computer: $ComputerName"

# Check if terminal server
if (Test-TerminalServer -ComputerName $ComputerName) {
Write-Verbose "[Main] Terminal server detected; exiting script"
Write-Output "Terminal server detected; drive mapping skipped."
exit 0
}

# Extract site code
$siteCode = Get-SiteCode -ComputerName $ComputerName
if (-not $siteCode) {
Write-Error "[Main] Failed to extract site code from computer name: $ComputerName"
exit 1
}

Write-Verbose "[Main] Site code: $siteCode"

# Lookup site configuration
if (-not $SiteConfig.ContainsKey($siteCode)) {
Write-Error "[Main] Site code '$siteCode' not found in configuration. Available sites: $($SiteConfig.Keys -join ', ')"
exit 1
}

$config = $SiteConfig[$siteCode]
Write-Verbose "[Main] Configuration found for site: $siteCode"
Write-Verbose "[Main] UserServer: $($config.UserServer), GroupServer: $($config.GroupServer)"

# Build UNC paths
$userUNC = "\\$($config.UserServer)\$env:USERNAME`$"
$groupUNC = "\\$($config.GroupServer)\$($config.GroupShare)"

Write-Verbose "[Main] User UNC path: $userUNC"
Write-Verbose "[Main] Group UNC path: $groupUNC"

# Disconnect existing drives
Write-Verbose "[Main] Disconnecting existing drives"
Disconnect-MappedDrive -DriveLetter 'u' -Force $true | Out-Null
Disconnect-MappedDrive -DriveLetter 'w' -Force $true | Out-Null
if ($config.SShare) {
Disconnect-MappedDrive -DriveLetter 's' -Force $true | Out-Null
}

# Map U: drive (user directory)
Write-Output "Connecting to User Directory on $($config.UserServer)..."
Write-Verbose "[Main] Mapping U: drive"
$uDriveSuccess = Connect-NetworkDrive -DriveLetter 'u' -UNCPath $userUNC -Persist $true

if (-not $uDriveSuccess) {
Write-Error "[Main] Failed to map U: drive; aborting script"
exit 1
}

# Map W: drive (group directory)
Write-Output "Connecting to Workgroup Directory on $($config.GroupServer)..."
Write-Verbose "[Main] Mapping W: drive"
$wDriveSuccess = Connect-NetworkDrive -DriveLetter 'w' -UNCPath $groupUNC -Persist $true

if (-not $wDriveSuccess) {
Write-Error "[Main] Failed to map W: drive; U: drive may still be mapped"
exit 1
}

# Map S: drive if configured
if ($config.SShare) {
Write-Output "Connecting to Branch Groups Directory..."
Write-Verbose "[Main] Mapping S: drive to $($config.SShare)"
$sDriveSuccess = Connect-NetworkDrive -DriveLetter 's' -UNCPath $config.SShare -Persist $true

if (-not $sDriveSuccess) {
Write-Warning "[Main] Failed to map S: drive, but U: and W: are successfully mapped"
}
}

Write-Verbose "[Main] Drive mapping completed successfully"
Write-Output "Drive mapping completed successfully for site: $siteCode"

exit 0

}


Loading
Loading