Public/Get-HDTWorkspaceShareName.ps1
|
function Get-HDTWorkspaceShareName { <# .SYNOPSIS The share name a deployment share should be published under, and the deploy root that follows from it. .DESCRIPTION A DEPLOYMENT SHARE IS A SHARE. MDT's New Deployment Share wizard asks for a folder AND a share name, creates the SMB share, and Bootstrap.ini's DeployRoot is \\<server>\<share> derived from the two. HDT asked for the UNC instead - a box somebody filled in by hand, naming a share nothing had created. THE SERVER IS THE COMPUTER NAME, NOT AN IP ADDRESS, and this repository has the argument written down twice: a lab host's address is a DHCP lease that moves when somebody changes the Wi-Fi, and DeployRoot is baked into the boot image. A name survives what an octet does not. MDT derives \\%servername%\Share$ for exactly this reason. THE DOLLAR IS NOT DECORATION. MDT's default share name ends in one, which keeps it out of network browsing - and a deployment share holds Control\share-credential.json, which is obfuscated rather than encrypted. A name given without one gets one. IT DECIDES; IT DOES NOT PUBLISH. Creating the share is New-HDTWorkspaceShare's job, through an injected ISmbService. This is the decision that command and the New Deployment Share dialog both read, which is why it can be asserted with no SMB stack at all. .PARAMETER Path The folder the share is over. Its leaf is the suggested share name. .PARAMETER ShareName The name to publish under. Omitted, the folder's leaf is used. .PARAMETER ServerName The machine the share lives on, as it will be WRITTEN into the deploy root. Defaults to this one. NOT -ComputerName, deliberately: nothing here connects to anything, and a parameter by that name reads as a remoting target - the analyzer says so too, since every call with a literal is a finding about exposing a machine name. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.Management.Automation.PSCustomObject with ShareName, DeployRoot, IsValid and Message. .EXAMPLE Get-HDTWorkspaceShareName -Path 'C:\HDTLab\Share' Share$ on this machine, and \\<thismachine>\Share$. .LINK New-HDTWorkspaceShare #> [CmdletBinding()] [OutputType([pscustomobject])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyString()] [string] $Path, [Parameter(Position = 1)] [AllowEmptyString()] [string] $ShareName = '', [Parameter()] [AllowEmptyString()] [string] $ServerName = [System.Environment]::MachineName ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $wanted = $ShareName.Trim() if ([string]::IsNullOrWhiteSpace($wanted) -and -not [string]::IsNullOrWhiteSpace($Path)) { $wanted = [System.IO.Path]::GetFileName($Path.TrimEnd('\', '/')) } $answer = [pscustomobject] @{ ShareName = '' DeployRoot = '' IsValid = $false Message = '' } if ([string]::IsNullOrWhiteSpace($wanted)) { return $answer } # HIDDEN BY DEFAULT, which is MDT's default and the right one here. if (-not $wanted.EndsWith('$')) { $wanted = '{0}$' -f $wanted } $answer.ShareName = $wanted # WHAT WINDOWS ACCEPTS AS A SHARE NAME: no path separators, no spaces, none # of the reserved characters, and 80 characters at most. Checked here rather # than left to New-SmbShare, whose refusal names a parameter. $bare = $wanted.TrimEnd('$') if ($wanted.Length -gt 80 -or $bare -notmatch '^[A-Za-z0-9._-]+$') { $answer.Message = "'{0}' is not a share name. It is letters, digits, dot, dash and underscore - no spaces and no backslashes - up to 80 characters, ending in `$ so it does not appear in network browsing." -f $ShareName return $answer } if ([string]::IsNullOrWhiteSpace($ServerName)) { # A DEPLOY ROOT WITH AN EMPTY SERVER IN IT is the shape that reaches the # boot image and fails at the Welcome screen, hours later. $answer.Message = 'this machine did not say what it is called, so the deploy root cannot be worked out. Type one on the share''s properties instead.' return $answer } $answer.DeployRoot = '\\{0}\{1}' -f $ServerName, $wanted $answer.IsValid = $true return $answer } |