-1

Within the InitializeSetup() function among other actions, when the installer is ran, I would like the installer to retrieve the current UPN. The UserName variable is not sufficient enough. I have also tried methods discussed here utilizing the WTSQuerySessionInformation() function but they don't seem to return what I am looking for. Depending on the organization and setting the UPN should often return some sort of an email address which I am looking for. Can someone shed some light on how to return the full UPN value as a string? Thank you.

EDIT:

I have also tried the GetUserNameExW() function passing in value 8 as an input which refers to UserNamePrincipal, however I am returning an empty value it seems.

function GetUserNameExW(NameFormat: Integer; lpNameBuffer: string; var nSize: DWORD): Boolean;
  external 'GetUserNameExW@secur32.dll stdcall';
var
  NumChars: DWORD;
  OutStr: string;
  name: string;

begin
  SetLength(OutStr, NumChars);
  GetUserNameExW(8, OutStr, NumChars);
  name := Copy(OutStr,1,NumChars);
  • Maybe you want to call `GetUserNameExW(NameUserPrincipal, ...)`? See [Get UserPrincipalName of logged-on user when windows system has joined into Azure AD](https://stackoverflow.com/q/55427602/850848). – Martin Prikryl Feb 20 '22 at 19:03
  • See if calling PowerShell in Inno Setup can give you the desired values, https://stackoverflow.com/questions/53566550/get-microsoft-account-name-for-current-user-in-powershell – Lex Li Feb 20 '22 at 19:22
  • @MartinPrikryl I forgot to mention that I've tried something along those lines. Its in my updated post now. I do think it may be on the right track but it always sent me empty values. Not sure why. – StackOverknow Feb 20 '22 at 19:26
  • What does `GetUserNameExW` returns? true or false? If false, what does `SysErrorMessage(DLLGetLastError)` say? – Martin Prikryl Feb 21 '22 at 07:20
  • @MartinPrikryl I believe it returns False and the error message returns "No mapping between account names and security IDs was done" and I am not joking here but almost every number I input into GetUserNameExW except 2 returns a message in Chinese for some reason and when translated, it has nothing to do with the user account. – StackOverknow Feb 21 '22 at 14:35
  • @LexLi Can you provide an example of how to translate the syntax from PowerShell to InnoSetup? I know how to manually retrieve the value from a cmd but how does one programmatically retrieve it from the language of Inno? – StackOverknow Feb 21 '22 at 14:40
  • What PowerShell syntax does work for you? – Martin Prikryl Feb 21 '22 at 14:45
  • Not sure if this is PowerShell directly but the typical whoami /upn in a cmd brings up the full name I want. – StackOverknow Feb 21 '22 at 14:58
  • That does not help us much. Even the https://stackoverflow.com/q/55427602/850848#63511417 says that it produces the same result as `whoami /upn`. – Martin Prikryl Feb 21 '22 at 15:05
  • As the last resort solution, you can just run PowerShell or `whoami /upn` from Inno Setup to collect the information you need. For an example, see [Retrieve strong name of .NET assembly in Inno Setup](https://stackoverflow.com/q/45996803/850848). – Martin Prikryl Feb 21 '22 at 15:14
  • Well that is why I was posing the question how to translate that into Inno speak? Not sure where the angle is coming from, I was simply answering your question about how I manually retrieve the value. – StackOverknow Feb 21 '22 at 15:19
  • Btw, it's the problem that your installer is running with elevated privileges? Don't the code produce the correct UPN, if you run it with `PrivilegesRequired=lowest`? – Martin Prikryl Feb 21 '22 at 15:21
  • Your translation to Inno Setup is correct. After all, the fact that it works with `NameSamCompatible` proves that. – Martin Prikryl Feb 21 '22 at 15:23
  • Based on your other question, I would point out that in many (most?) environments, userPrincipalName is not the same as the user's email address. They are two completely separate attributes. – Bill_Stewart Feb 22 '22 at 17:42

2 Answers2

1

The correct code to call GetUserNameExW to get the current user's userPrincipalName (UPN) attribute would look like this:

function GetUserNameExW(NameFormat: Integer; lpNameBuffer: string; var nSize: DWORD): Boolean;
  external 'GetUserNameExW@secur32.dll stdcall';

function GetUserPrincipalName(): string;
var
  NumChars: DWORD;
  OutStr: string;
begin
  result := '';
  NumChars := 0;
  if (not GetUserNameExW(8, '', NumChars)) and (DLLGetLastError() = 234) then
  begin
    SetLength(OutStr, NumChars);
    if GetUserNameExW(8, OutStr, NumChars) then
      result := Copy(OutStr, 1, NumChars);
  end;
end;

The value 8 for the NameFormat parameter corresponds to NameUserPrincipal in the EXTENDED_NAME_FORMAT enumeration, and the value 234 is API value ERROR_MORE_DATA.

However--as I pointed out in a comment--if you are looking for an email address, this would not be the code to do that because userPrincipalName (UPN) is a separate user attribute (in fact, in many, if not most organizations, the UPN is different from the user's email address). Also, if you are assuming the UPN to be the same as one of the user's email email addresses, this would also be an incorrect assumption, as the UPN's value is very often not in the list of valid email addresses for a user.

The point is that if you are looking for a reliable way to get a valid email address for a user, the UPN is not going give you one.

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • To be fair, I have the error check but didn't include in my sample for brevity. In my solution I also called the if GetUserNameExW statement the same way you did. There is no difference in my solution from yours. @MartinPrikryl seems to believe the if statement has no bearing but won't admit he's wrong. – StackOverknow Feb 23 '22 at 16:49
-2

I have managed to the solve this issue myself but still not 100% sure on why my previous iteration resulted in odd behavior.

Essentially, I had to add an if check before:

if GetUserNameExW(8, OutStr, NumChars) then
  • Calling the function within `if` does not have any effect on the function result. – Martin Prikryl Feb 21 '22 at 15:54
  • Like I mentioned in my post I am not sure whats the cause of the unexpected behavior but putting the if statement gave me the solution to my question when before running ExW without the if resulted in a blank. While I appreciate your feedback, none of your solutions worked for me. And while on paper it doesn't sound like it would, the fact that I am now able to get the UPN by using the if statement shows IT DOES affect the outcome. – StackOverknow Feb 21 '22 at 17:06
  • 1
    See my answer for the correct way to call the API, and for why you should not expect the `userPrincipalName` attribute to be an email address (it isn't). – Bill_Stewart Feb 22 '22 at 20:47