datum icon indicating copy to clipboard operation
datum copied to clipboard

prevent early resolving of Powershell variables by using .NET Combine

Open stehlih opened this issue 2 years ago • 4 comments

prevent early resolving of Powershell variables by using .NET Combine instead of Join-Path

We are using code like the follwoing in the datum.yml:

ResolutionPrecedence: ...

  • LCM$($ro=$Node.Role.Split(''); $ro[0])\LCM$($env:BuildLcmMode)_AddOn ...
  • LCM\LCM_$($env:BuildLcmMode)

In this case the original Join-Path produces an runtime error (illegal path) which can be avoid by using the .NET Combine.

stehlih avatar May 01 '22 11:05 stehlih

The combine usually does not play well with psdrive. Could you 'convert-path' first?

gaelcolas avatar May 01 '22 12:05 gaelcolas

In the Powershell documentation I found the note: Convert-Path only converts existing paths. It cannot be used to convert a location that does not exist yet.

But in the ResolutionPrecedence only the childpath is prepared.

The problem is the use of the following code: $($env:BuildLcmMode)

which produce the following error: Drive doesn't exist. A drive with name "Roles..." was not found.

Join-Path : Das Laufwerk wurde nicht gefunden. Ein Laufwerk mit dem Namen "Roles$($ro=$Node.Role.Split('_'); $ro[0])$($env" ist nicht vorhanden. In D:\Repository\WSP-Core\Impl\DscRefConfig\Output\output\RequiredModules\datum\0.40.1\datum.psm1:1995 Zeichen:26

  • ... urrentSearch = Join-Path -Path $searchPrefix -ChildPath $PropertyPath
    • CategoryInfo : ObjectNotFound: (Roles$($ro=$No... $ro[0])$($env:String) [Join-Path], DriveNotFoundException
    • FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.JoinPathCommand

After drop of this part Join-Path works without errors. But I can't found a working replacement to get the value of an environment variable which is required to build the right YAML file name.

stehlih avatar May 01 '22 15:05 stehlih

@gaelcolas, remember. When going through the code we were not sure why we replaces Join-Path with [System.IO.Path]::Combine.

Besides in Pester tests, when are we dealing with PSDrives other then the normal file drives?

raandree avatar May 01 '22 21:05 raandree

@gaelcolas, I don't see a reason why we should stick to Join-Path over [System.IO.Path]::Combine in this case.

When trying to do something similar like @stehlih, I get this error:

Join-Path : Cannot find drive. A drive with the name 'Baselines\$($env' does not exist.
At D:\DscWorkshop-1\output\RequiredModules\datum\0.40.1\datum.psm1:1995 char:26
+ ... urrentSearch = Join-Path -Path $searchPrefix -ChildPath $PropertyPath
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Baselines\$($env:String) [Join-Path], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.JoinPathCommand

I have assigned a value to an environment variable:

$env:DscBaseline = 'DscLcm'

and used it in the datum.yml like this:

ResolutionPrecedence:
  - AllNodes\$($Node.Environment)\$($Node.NodeName)
  - Environment\$($Node.Environment)
  - Locations\$($Node.Location)
  - Roles\$($Node.Role)
  - Baselines\Security
  - Baselines\$($Node.Baseline)
  - Baselines\$($env:DscBaseline)

Everything works fine with the proposed change.

raandree avatar Aug 16 '22 17:08 raandree