@@ -75,6 +75,12 @@ function Import-Yaml {
7575
7676 . OUTPUTS
7777 System.Object
78+
79+ . NOTES
80+ Only FileSystem provider paths are supported.
81+
82+ . LINK
83+ ConvertFrom-Yaml
7884 #>
7985 [OutputType ([object ])]
8086 [CmdletBinding (DefaultParameterSetName = ' Path' )]
@@ -226,19 +232,9 @@ function Import-Yaml {
226232 )
227233 $PSCmdlet.ThrowTerminatingError ($record )
228234 }
229- if (-not [System.IO.File ]::Exists($providerPath )) {
230- if ([System.IO.Directory ]::Exists($providerPath )) {
231- $exception = [System.IO.IOException ]::new(
232- " Cannot import YAML from '$requestedPath ': the path is not a file."
233- )
234- $record = [System.Management.Automation.ErrorRecord ]::new(
235- $exception ,
236- ' YamlImportNotFile' ,
237- [System.Management.Automation.ErrorCategory ]::InvalidType,
238- $requestedPath
239- )
240- $PSCmdlet.ThrowTerminatingError ($record )
241- }
235+ try {
236+ $pathAttributes = [System.IO.File ]::GetAttributes($providerPath )
237+ } catch [System.IO.FileNotFoundException ] {
242238 $exception = [System.IO.FileNotFoundException ]::new(
243239 " Cannot import YAML from '$requestedPath ': the path was not found."
244240 )
@@ -249,6 +245,55 @@ function Import-Yaml {
249245 $requestedPath
250246 )
251247 $PSCmdlet.ThrowTerminatingError ($record )
248+ } catch [System.IO.DirectoryNotFoundException ] {
249+ $exception = [System.IO.FileNotFoundException ]::new(
250+ " Cannot import YAML from '$requestedPath ': the path was not found."
251+ )
252+ $record = [System.Management.Automation.ErrorRecord ]::new(
253+ $exception ,
254+ ' YamlImportPathNotFound' ,
255+ [System.Management.Automation.ErrorCategory ]::ObjectNotFound,
256+ $requestedPath
257+ )
258+ $PSCmdlet.ThrowTerminatingError ($record )
259+ } catch [System.UnauthorizedAccessException ] {
260+ $inspectionError = $_
261+ $exception = [System.IO.IOException ]::new(
262+ " Cannot inspect YAML input path '$requestedPath ': $ ( $inspectionError.Exception.Message ) " ,
263+ $inspectionError.Exception
264+ )
265+ $record = [System.Management.Automation.ErrorRecord ]::new(
266+ $exception ,
267+ ' YamlImportPermissionDenied' ,
268+ [System.Management.Automation.ErrorCategory ]::PermissionDenied,
269+ $requestedPath
270+ )
271+ $PSCmdlet.ThrowTerminatingError ($record )
272+ } catch [System.IO.IOException ] {
273+ $inspectionError = $_
274+ $exception = [System.IO.IOException ]::new(
275+ " Cannot inspect YAML input path '$requestedPath ': $ ( $inspectionError.Exception.Message ) " ,
276+ $inspectionError.Exception
277+ )
278+ $record = [System.Management.Automation.ErrorRecord ]::new(
279+ $exception ,
280+ ' YamlImportPathInspectionFailed' ,
281+ [System.Management.Automation.ErrorCategory ]::ReadError,
282+ $requestedPath
283+ )
284+ $PSCmdlet.ThrowTerminatingError ($record )
285+ }
286+ if (($pathAttributes -band [System.IO.FileAttributes ]::Directory) -ne 0 ) {
287+ $exception = [System.IO.IOException ]::new(
288+ " Cannot import YAML from '$requestedPath ': the path is not a file."
289+ )
290+ $record = [System.Management.Automation.ErrorRecord ]::new(
291+ $exception ,
292+ ' YamlImportNotFile' ,
293+ [System.Management.Automation.ErrorCategory ]::InvalidType,
294+ $requestedPath
295+ )
296+ $PSCmdlet.ThrowTerminatingError ($record )
252297 }
253298 $resolvedPaths.Add ([System.IO.Path ]::GetFullPath($providerPath ))
254299 continue
@@ -337,7 +382,36 @@ function Import-Yaml {
337382 )
338383 $PSCmdlet.ThrowTerminatingError ($record )
339384 }
340- if (-not [System.IO.File ]::Exists($pathInfo.ProviderPath )) {
385+ try {
386+ $pathAttributes = [System.IO.File ]::GetAttributes($pathInfo.ProviderPath )
387+ } catch [System.UnauthorizedAccessException ] {
388+ $inspectionError = $_
389+ $exception = [System.IO.IOException ]::new(
390+ " Cannot inspect YAML input path '$ ( $pathInfo.Path ) ': $ ( $inspectionError.Exception.Message ) " ,
391+ $inspectionError.Exception
392+ )
393+ $record = [System.Management.Automation.ErrorRecord ]::new(
394+ $exception ,
395+ ' YamlImportPermissionDenied' ,
396+ [System.Management.Automation.ErrorCategory ]::PermissionDenied,
397+ $pathInfo.Path
398+ )
399+ $PSCmdlet.ThrowTerminatingError ($record )
400+ } catch [System.IO.IOException ] {
401+ $inspectionError = $_
402+ $exception = [System.IO.IOException ]::new(
403+ " Cannot inspect YAML input path '$ ( $pathInfo.Path ) ': $ ( $inspectionError.Exception.Message ) " ,
404+ $inspectionError.Exception
405+ )
406+ $record = [System.Management.Automation.ErrorRecord ]::new(
407+ $exception ,
408+ ' YamlImportPathInspectionFailed' ,
409+ [System.Management.Automation.ErrorCategory ]::ReadError,
410+ $pathInfo.Path
411+ )
412+ $PSCmdlet.ThrowTerminatingError ($record )
413+ }
414+ if (($pathAttributes -band [System.IO.FileAttributes ]::Directory) -ne 0 ) {
341415 $exception = [System.IO.IOException ]::new(
342416 " Cannot import YAML from '$ ( $pathInfo.Path ) ': the path is not a file."
343417 )
@@ -353,17 +427,71 @@ function Import-Yaml {
353427 }
354428 }
355429
356- $pathComparer = if ($IsWindows ) {
357- [System.StringComparer ]::OrdinalIgnoreCase
358- } else {
430+ $caseSensitivePaths = [System.Collections.Generic.HashSet [string ]]::new(
359431 [System.StringComparer ]::Ordinal
360- }
361- $uniquePaths = [System.Collections.Generic.HashSet [string ]]::new($pathComparer )
432+ )
433+ $caseInsensitivePaths = [System.Collections.Generic.HashSet [string ]]::new(
434+ [System.StringComparer ]::OrdinalIgnoreCase
435+ )
362436 foreach ($resolvedPath in $resolvedPaths ) {
363- $null = $uniquePaths.Add ($resolvedPath )
437+ $useCaseSensitiveIdentity = -not $IsWindows
438+ if ($IsWindows ) {
439+ $identityPath = $resolvedPath
440+ while (-not [string ]::IsNullOrEmpty($identityPath )) {
441+ $directoryPath = [System.IO.Path ]::GetDirectoryName($identityPath )
442+ if ([string ]::IsNullOrEmpty($directoryPath )) {
443+ break
444+ }
445+ $leafName = [System.IO.Path ]::GetFileName($identityPath )
446+ try {
447+ $caseVariantCount = 0
448+ foreach ($directoryEntry in (
449+ [System.IO.Directory ]::EnumerateFileSystemEntries($directoryPath )
450+ )) {
451+ if ([string ]::Equals(
452+ [System.IO.Path ]::GetFileName($directoryEntry ),
453+ $leafName ,
454+ [System.StringComparison ]::OrdinalIgnoreCase
455+ )) {
456+ $caseVariantCount ++
457+ if ($caseVariantCount -gt 1 ) {
458+ $useCaseSensitiveIdentity = $true
459+ break
460+ }
461+ }
462+ }
463+ } catch [System.UnauthorizedAccessException ] {
464+ $useCaseSensitiveIdentity = $true
465+ } catch [System.IO.IOException ] {
466+ $useCaseSensitiveIdentity = $true
467+ }
468+ if ($useCaseSensitiveIdentity -or
469+ [string ]::Equals(
470+ $identityPath ,
471+ $directoryPath ,
472+ [System.StringComparison ]::Ordinal
473+ )) {
474+ break
475+ }
476+ $identityPath = $directoryPath
477+ }
478+ }
479+
480+ if ($useCaseSensitiveIdentity ) {
481+ $null = $caseSensitivePaths.Add ($resolvedPath )
482+ } else {
483+ $null = $caseInsensitivePaths.Add ($resolvedPath )
484+ }
485+ }
486+ $uniquePaths = [System.Collections.Generic.List [string ]]::new()
487+ foreach ($uniquePath in $caseSensitivePaths ) {
488+ $uniquePaths.Add ($uniquePath )
489+ }
490+ foreach ($uniquePath in $caseInsensitivePaths ) {
491+ $uniquePaths.Add ($uniquePath )
364492 }
365493 [string []] $orderedPaths = $uniquePaths
366- [System.Array ]::Sort($orderedPaths , $pathComparer )
494+ [System.Array ]::Sort($orderedPaths , [ System.StringComparer ]::Ordinal )
367495
368496 foreach ($resolvedPath in $orderedPaths ) {
369497 try {
0 commit comments