Details
-
Bug
-
Status: Resolved
-
High
-
Resolution: Duplicate
-
FACT 3.13.0
-
None
-
None
-
None
-
facter: 3.13.0
puppet: 6.3.0
os: Windows Server 2012 R2
-
Night's Watch
-
NW - 2020-01-22
-
Needs Assessment
-
Not Needed
-
Needs Assessment
Description
We have come across an environment where facter is not reporting the correct data for the os.windows.system32 fact. We have successfully deployed the Puppet agent on other environments many times with no issue.
When we install the puppet agent, start a new PowerShell session and run facter os.windows the value returned is "C:\Users\username\WINDOWS\system32" instead of the expected "C:\Windows\system32"
The username changes based on who is running the command.
We get the same result regardless of whether we use a cmd or PowerShell prompt and whether it's a standard or Administrator.
We have tried this on 2 systems in this environment with the same result which seems to indicate an environment rather than an individual system issue.
Running set at a cmd prompt or Get-ChildItem in PowerShell reports the following expected settings:
SystemDrive C:
SystemRoot C:\Windows
UserProfile C:\Users\username
A search of the internet led us to this link which seems to be where the fact is determined:
https://github.com/puppetlabs/facter/blob/master/lib/src/facts/windows/operating_system_resolver.cc#L56
Using information found here http://pinvoke.net/default.aspx/shell32/SHGetFolderPath.html, we managed to translate the C++ source code in a C# type to add to PowerShell so we could see what was being returned. This is the code we came up with:
Add-Type @"
using System;
using System.Text;
using System.Runtime.InteropServices;
public class shell32
{
[DllImport("shell32.dll")]
private static extern int SHGetFolderPath(
IntPtr hwnd,
int csidl,
IntPtr hToken,
uint dwFlags,
[Out] StringBuilder pszPath
);
public static string GetKnownFolderPath()
{
const int MaxPath = 260;
StringBuilder sb = new StringBuilder(MaxPath);
if (SHGetFolderPath(IntPtr.Zero, 0x0024, IntPtr.Zero, 0x0000, sb) != 0)
return "failed"; // add whatever error handling you fancy
return sb.ToString();
{
}}
{
}}
"@
When we run the following:
.\SHGetKnownFolderPath.ps1
[shell32]::GetKnownFolderPath()
we get the expected output:
C:\Windows
Which doesn't help at all.
We can probably work around getting the incorrect data in our Puppet manifests but that doesn't help for anything on the forge that might rely on that fact.
Initially we need help in determining why/how this is happening so this can then be fed back for further analysis and a plan of action determined whether that be a change in the environment to modifications to the facter code.
The below information is not directly related to the issue but is included for reference.
There is also this pull request that seems to want to change this code to use the correct CSIDL:
https://github.com/puppetlabs/facter/pull/1856
https://github.com/puppetlabs/facter/commit/4dd82b9460752636b817428970a72769ef47a023
The Microsoft documentation also says that SHGetFolderPath deprecated and is now a wrapper for SHGetKnownFolderPath so maybe the code should also be updated to use the new function.
https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpatha
Attachments
Issue Links
- relates to
-
FACT-2096 Windows system32 environment variable issue after installation of "RDS-RD-Server"
-
- Resolved
-