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
13 changes: 7 additions & 6 deletions src/System.Management.Automation/engine/SessionStateDriveAPIs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -508,12 +508,13 @@ private PSDriveInfo GetDrive(string name, bool automount)

if (result == null && automount)
{
result = AutomountBuiltInDrive(name);
}

if (result == null && this == ExecutionContext.TopLevelSessionState)
{
result = AutomountFileSystemDrive(name);
// first try to automount as a file system drive
result = AutomountFileSystemDrive(name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old code only created file system drives if the current scope was global.
Will your change create the drive in global scope or module scope?
Personally, I would expect the drive to be in global scope.
I would also like to see tests to cover that scenario either way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this change, new drives will be created in global scope; I've added a check for this to tests.

// if it didn't work, then try automounting as a BuiltIn drive (e.g. "Cert"/"Certificate"/"WSMan")
if (result == null)
{
result = AutomountBuiltInDrive(name); // internally this calls GetDrive(name, false)
}
}

if (result == null)
Expand Down
38 changes: 38 additions & 0 deletions test/powershell/Provider/AutomountSubstDrive.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Precondition: start from fresh PS session, do not have the media mounted
param([switch]$useModule, [string]$FullPath)

$global:CoreScriptPath = Join-Path $PSScriptRoot 'AutomountSubstDriveCore.ps1'

if ($useModule)
{
$m = New-Module {
function Test-DrivePresenceFromModule
{
param ([String]$Path)

& $global:CoreScriptPath -Path $Path
}

Export-ModuleMember -Function Test-DrivePresenceFromModule
}
}

try
{
if ($useModule)
{
Import-Module $m -Force
Test-DrivePresenceFromModule -Path $FullPath
}
else
{
& $global:CoreScriptPath -Path $FullPath
}
}
finally
{
if ($useModule)
{
Remove-Module $m
}
}
31 changes: 31 additions & 0 deletions test/powershell/Provider/AutomountSubstDriveCore.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
param ([String]$Path)

try
{
# Get a drive letter between F and Y that is not being used for the drive name.
$driveLetter = [char[]](70..89) | Where-Object {$_ -notin (Get-PSDrive).Name} | Select-Object -Last 1

$dir = New-Item $Path -ItemType Directory -Force

# Create virtual drive pointing to the parent of the directory
subst.exe "$driveLetter`:" $dir.Parent.FullName
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { Write-Error "Creating drive with subst.exe failed with exit code $exitCode" }

$root = [String]::Format('{0}:\', $driveLetter)
$pathToCheck = Join-Path -Path $root -ChildPath $dir.Name

if (Test-Path $pathToCheck)
{
"Drive found"
if (-not (Get-PSDrive -Name $driveLetter -Scope Global -ErrorAction SilentlyContinue))
{
Write-Error "Drive is NOT in Global scope"
}
}
else { Write-Error "$pathToCheck not found" }
}
finally
{
subst.exe "$driveLetter`:" /d
}
76 changes: 76 additions & 0 deletions test/powershell/Provider/AutomountVHDDrive.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Precondition: start from fresh PS session, do not have the media mounted
param([switch]$useModule, [string]$VHDPath)

function CreateVHD ($VHDPath, $Size)
{
$drive = (New-VHD -path $vhdpath -SizeBytes $size -Dynamic | `
Mount-VHD -Passthru | `
get-disk -number {$_.DiskNumber} | `
Initialize-Disk -PartitionStyle MBR -PassThru | `
New-Partition -UseMaximumSize -AssignDriveLetter:$False -MbrType IFS | `
Format-Volume -Confirm:$false -FileSystem NTFS -force | `
get-partition | `
Add-PartitionAccessPath -AssignDriveLetter -PassThru | `
get-volume).DriveLetter

$drive
}

if ($useModule)
{
$m = New-Module {
function Test-DrivePresenceFromModule
{
param ([String]$Path)

if (Test-Path $Path)
{
"Drive found"
if (-not (Get-PSDrive -Name $Path[0] -Scope Global -ErrorAction SilentlyContinue))
{
Write-Error "Drive is NOT in Global scope"
}
}
else { Write-Error "$Path not found" }
}

Export-ModuleMember -Function Test-DrivePresenceFromModule
}
}

try
{
if ($useModule)
{
Import-Module $m -Force
}

$drive = CreateVHD -VHDPath $VHDPath -Size 5mb
$pathToCheck = "${drive}:"

if ($useModule)
{
Test-DrivePresenceFromModule -Path $pathToCheck
}
else
{
if (Test-Path $pathToCheck)
{
"Drive found"
if (-not (Get-PSDrive -Name $drive -Scope Global -ErrorAction SilentlyContinue))
{
Write-Error "Drive is NOT in Global scope"
}
}
else { Write-Error "$pathToCheck not found" }
}
}
finally
{
if ($useModule)
{
Remove-Module $m
}
Dismount-VHD $VHDPath
Remove-Item $VHDPath
}
55 changes: 55 additions & 0 deletions test/powershell/Provider/Pester.AutomountedDrives.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<############################################################################################
# File: Pester.AutomountedDrives.Tests.ps1
# Pester.AutomountedDrives.Tests suite contains Tests that are
# used for validating automounted PowerShell drives.
############################################################################################>
$script:TestSourceRoot = $PSScriptRoot
Describe "Test suite for validating automounted PowerShell drives" -Tags "CI","Slow" {

BeforeAll {
$powershell = Join-Path -Path $PsHome -ChildPath "powershell"

$AutomountVHDDriveScriptPath = Join-Path $script:TestSourceRoot 'AutomountVHDDrive.ps1'
$vhdPath = Join-Path $TestDrive 'TestAutomountVHD.vhd'

$AutomountSubstDriveScriptPath = Join-Path $script:TestSourceRoot 'AutomountSubstDrive.ps1'
$substDir = Join-Path (Join-Path $TestDrive 'TestAutomountSubstDrive') 'TestDriveRoot'
New-Item $substDir -ItemType Directory -Force | Out-Null

$SubstNotFound = $false
try { subst.exe } catch { $SubstNotFound = $true }

$VHDToolsNotFound = $false
try
{
$tmpVhdPath = Join-Path $TestDrive 'TestVHD.vhd'
New-VHD -path $tmpVhdPath -SizeBytes 5mb -Dynamic -ErrorAction Stop
Remove-Item $tmpVhdPath
}
catch
{ $VHDToolsNotFound = $true }
}

Context "Validating automounting FileSystem drives" {

It "Test automounting using subst.exe" -Skip:$SubstNotFound {
& $powershell -noprofile -command "& '$AutomountSubstDriveScriptPath' -FullPath '$substDir'" | Should Be "Drive found"
}

It "Test automounting using New-VHD/Mount-VHD" -Skip:$VHDToolsNotFound {
& $powershell -noprofile -command "& '$AutomountVHDDriveScriptPath' -VHDPath '$vhdPath'" | Should Be "Drive found"
}
}

Context "Validating automounting FileSystem drives from modules" {

It "Test automounting using subst.exe" -Skip:$SubstNotFound {
& $powershell -noprofile -command "& '$AutomountSubstDriveScriptPath' -useModule -FullPath '$substDir'" | Should Be "Drive found"
}

It "Test automounting using New-VHD/Mount-VHD" -Skip:$VHDToolsNotFound {
$vhdPath = Join-Path $TestDrive 'TestAutomountVHD.vhd'
& $powershell -noprofile -command "& '$AutomountVHDDriveScriptPath' -useModule -VHDPath '$vhdPath'" | Should Be "Drive found"
}
}
}