Public/FileTransfer/Copy-VmFilesByPattern.ps1
|
<#
.SYNOPSIS Copies host files matching a wildcard pattern to a Hyper-V VM. .DESCRIPTION Thin public wrapper that combines two existing primitives: 1. Resolve-VmFileEntries (private) expands the host-side wildcard into the entry shape Copy-VmFiles consumes and runs the pre-flight validation pass. 2. Copy-VmFiles (public) performs the per-entry transport. Validation lives entirely in the resolver - if it throws, no SSH or file-server I/O happens, which is the contract documented in docs\dev\implementation\01 - bulk-vm-file-transfer\problem.md. .PARAMETER SshClient A live Renci.SshNet.SshClient. The caller owns the client's lifecycle. Forwarded to Copy-VmFiles unchanged. .PARAMETER Server A file-server handle returned by Start-VmFileServer or supplied by Invoke-WithVmFileServer's scriptblock. Forwarded to Copy-VmFiles unchanged. .PARAMETER Pattern A host-side wildcard accepted by Get-ChildItem -Path. Forwarded to the resolver. .PARAMETER TargetDir Absolute Linux directory on the VM under which every matched file lands. Forwarded to the resolver. .PARAMETER Recurse Descend into subdirectories. Forwarded to the resolver. .PARAMETER PreserveRelativePath Mirror the host subtree under TargetDir instead of flattening to basenames. Forwarded to the resolver. .PARAMETER Owner chown argument applied uniformly to every entry. When omitted the resolver's default ('root:root') applies. .PARAMETER Mode chmod argument applied uniformly to every entry. When omitted the resolver's default ('0644') applies. .EXAMPLE Invoke-WithVmFileServer -VmIpAddress '10.10.0.50' -ScriptBlock { param($server) $sshClient = New-VmSshClient -IpAddress '10.10.0.50' ` -Username 'admin' -Password 'secret' try { Copy-VmFilesByPattern -SshClient $sshClient -Server $server ` -Pattern 'C:\seed\*.json' ` -TargetDir '/var/data' } finally { if ($sshClient.IsConnected) { $sshClient.Disconnect() } $sshClient.Dispose() } } #> function Copy-VmFilesByPattern { [CmdletBinding()] param( [Parameter(Mandatory)] [object] $SshClient, [Parameter(Mandatory)] [object] $Server, [Parameter(Mandatory)] [string] $Pattern, [Parameter(Mandatory)] [string] $TargetDir, [switch] $Recurse, [switch] $PreserveRelativePath, [string] $Owner, [string] $Mode ) # Forward only the file-selection parameters the caller actually # supplied. This keeps the resolver as the single source of truth # for Owner / Mode defaults instead of restating them here. $resolveArgs = @{ Pattern = $Pattern TargetDir = $TargetDir } if ($Recurse) { $resolveArgs.Recurse = $true } if ($PreserveRelativePath) { $resolveArgs.PreserveRelativePath = $true } if ($PSBoundParameters.ContainsKey('Owner')) { $resolveArgs.Owner = $Owner } if ($PSBoundParameters.ContainsKey('Mode')) { $resolveArgs.Mode = $Mode } $entries = Resolve-VmFileEntries @resolveArgs Copy-VmFiles -SshClient $SshClient -Server $Server -Entries $entries } |