How to get an Azure Active Directory username in Windows Powershell? - powershell

I'm trying to get the current Windows username & domain from Powershell on a Windows 10 Azure Active Directory (AAD) joined machine.
I've tried the tips at this question, but none of them seem to work for Azure Active Directory-joined machines.
e.g. for the user: Jonathan Doe, john#example.com you'll get only the users' proper name & AzureAD (not their username or 'real' domain):
$env:UserName --> JonathanDoe
$env:UserDomain --> AzureAD
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name --> AzureAD\JonathanDoe
Does anyone know how to get any part of the user's actual credential or specific Azure AAD domain? (e.g. john or example.com or ideally john#example.com)

You can run the following command in PowerShell, the output will display the user name in UPN format.You can get both of the username and domain name from that.
whoami.exe /UPN
In addition, the program 'whoami.exe' provides many other parameters for getting additional information about current user. You can type the following command for more details about 'whoami.exe'.
whoami.exe /?

I'm not sure how official this is, but I found a link in the registry that contains the username which is user#company.com. This was under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\IdentityStore\Cache\xxx\IdentityCache\xxx. The key name was UserName. You can use the built-in powershell registry provider to navigate to this registry entry.

Related

Search-Mailbox cmdlet availability with app-only authentication in Exchange Online

I'm connecting to Exchange Online using PowerShell and the following command:
Connect-ExchangeOnline -AppId APP_ID -CertificateFilePath CERTIFICATE_PATH -Organization ORG_NAME
And would like to use the "Search-Mailbox" cmdlet.
The docs say:
By default, Search-Mailbox is available only in the Mailbox Search or Mailbox Import Export roles, and these roles aren't assigned to any role groups.
The app has the Exchange administrator role assigned in Azure.
In Exchange admin center, I added Exchange administrators to the Discovery Management role group that has the Mailbox Search role enabled.
After reconnecting, Search-Mailbox is still not available:
Search-Mailbox: The term 'Search-Mailbox' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Could someone please explain why it doesn't work and how to make it work?
It worked after I assigned "Mailbox Search" role to the "Organization Management" role group (Exchange administrators role groups inherits from it).
When the CmdLet is not available it needs to be imported, installed or run on the correct server. It seems like Search-Mailbox is part of the module ExchangePowerShell.
I believe you either need to import the module in your PowerShell session:
Import-Module -Name 'ExchangePowerShell'
Or run the CmdLet on the Exchange server directly or use Connect-ExchangeOnline.

Why would $env:username and [environment]::username return different users?

What is the difference between PowerShell's $env:username and [environment]::username and why would they potentially return different users? (I understand there are other ways to get the current user as well)
Some background:
I have an Azure Pipeline that runs a PowerShell script on a release target. The pipeline agent is configured to run under a specific service account. Part of that PowerShell script uses $env:username to assign permissions. However, permissions are assigned to the local admin account instead. If I change the script to use [environment]::username the correct service account user is given permissions.
$env:USERNAME, while predefined to reflect the current user's username, is a read-write environment variable, just like any other.
Even though it's obviously inadvisable to do so, a statement such as $env:USERNAME = 'foo' changes the value of environment variable USERNAME for the current process as well as its child processes.
This means that if environment variable USERNAME was modified earlier in the same session or in PowerShell's parent process, possibly via an explicitly specified startup environment, it no longer reflects the true username.
While I don't know why the USERNAME environment variable would differ from the real account in the case of Azure Pipelines, an example of - inadvertently - setting the wrong value is PowerShell's Start-Process cmdlet when given the -UseNewEnvironment switch: due to a bug as of PowerShell Core 7.0.0-preview.5 / Windows PowerShell v5.1, $env:USERNAME unexpectedly always reflects SYSTEM, irrespective of the actual user account - see this GitHub issue.
By contrast, [Environment]::UserName uses a different method for obtaining the current user's username, which does not rely on the value of $env:USERNAME and always reflects the true username[1].
In short: Only [Environment]::UserName reliably reflects the current user account's username.
[1] From the linked docs: "On Windows the UserName property wraps a call to the Windows GetUserName function. The domain account credentials for a user are formatted as the user's domain name, the \ character, and user name. Use the UserDomainName property to obtain the user's domain name and the UserName property to obtain the user name.
On Unix platforms the UserName property wraps a call to the getpwuid_r function.
$env: is looking at your environmental variables. The variable that you're looking at- username- happens to be set to the local username by default. But it doesn't have to be.
[Environment] is a call to the System.Environment class in .NET Framework. This class has a property called UserName that contains the username that is logged into the computer.
Similiar names, but very different things. You could get the path statement by $env:Path, for example, or call [Environment]::Version to get the version of .NET Framework.
Note in this example I deliberately messed with the local environmental variable prior to launching PowerShell to give the wrong username.
C:\WINDOWS\system32>echo %username%
mspow
C:\WINDOWS\system32>set username=bob
C:\WINDOWS\system32>echo %username%
bob
C:\WINDOWS\system32>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\WINDOWS\system32> echo $env:username
bob
PS C:\WINDOWS\system32> [Environment]::Username
mspow
PS C:\WINDOWS\system32> echo $env:ProgramFiles
C:\Program Files
PS C:\WINDOWS\system32> echo $env:path
C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Users\mspow\AppData\Local\Microsoft\WindowsApps
PS C:\WINDOWS\system32> [Environment]::Version
Major Minor Build Revision
----- ----- ----- --------
4 0 30319 42000
You can see all of the available environment variables by using
Get-Item -Path Env:
The only way I know of to see all of the Methods and Properties for [Environment] is the link to the MSDN site. Get-Member doesn't work on it.

Windows: Delete specific Active Directory accounts via Powershell Script (remote)

folks,
my Active Directory accounts with admin privileges all start with the same characters: "ad" followed by a dot and the name of the admin. Example: "ad.tim".
I would like to have admin accounts (every account beginning with "ad.") automatically deleted (profiles and user data) by the Windows clients and would like to distribute a Powershell script to my clients (better ideas are welcome).
I'm not very familiar with Powershell nor Scripting, but I allready figured out (thanks, Google) how to list all Accounts:
Get-WMIObject -Class Win32_UserProfile | select LocalPath
Now I'd have to filter (-like ad.*) and delete, but I'm not sure how or where to install it. It would be great if someone could give me some information so that I can better understand it and reach my goal!

VBS script to retrieve user information from Azure Active Directory

This may not even be possible without powershell (or Azure Powershell), but can I use a script to retrieve user information from AZURE active directory on a Windows 10 computer?
Since the user has already provided credentials and the user name has been pulled down from Azure, is there any other information pulled down that I can reference as a system object (for eg).
Example of code to show user name:
Set objSysInfo = CreateObject("ADSystemInfo")
wScript.Echo objSysInfo.UserName
I want to see other information such as users department(i.e. .department , so that I can map drives by identifying the users department rather than using the user name).
If I can't use vbs then is this possible with Azure powershell without re-entering user credentials and/or re-verifying user credentials?
It's possible with Azure PowerShell commandlets:
Connect-MsolService -CurrentCredential
Get-MsolUser -UserPrincipalName username#domain

Specify domain controller with get-aduser in powershell

Get-ADUser -identity $ntaccount1 -properties name, samaccountname, mail, enabled, passwordlastset
Is it possible, when looking up the user account information in powershell, to specify a domain controller to use? We have some DC's that get the data faster than others.
From Get-Help Get-ADUser -Parameter *
-Server <string>
Specifies the Active Directory Domain Services instance to connect to, by providing one of the following values for a
corresponding domain name or directory server. The service may be any of the following: Active Directory Lightweight Domain
Services, Active Directory Domain Services or Active Directory Snapshot instance.
Domain name values:
Fully qualified domain name
Examples: corp.contoso.com
NetBIOS name
Example: CORP
Directory server values:
Fully qualified directory server name
Example: corp-DC12.corp.contoso.com
NetBIOS name
Example: corp-DC12
Fully qualified directory server name and port
Example: corp-DC12.corp.contoso.com:3268
The default value for the Server parameter is determined by one of the following methods in the order that they are listed:
-By using Server value from objects passed through the pipeline.
-By using the server information associated with the Active Directory PowerShell provider drive, when running under that drive.
-By using the domain of the computer running Powershell.
The following example shows how to specify a full qualified domain name as the parameter value.
-Server "corp.contoso.com"
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters? false
I know that this is a bit of an old question, but I would like to expand on the answer given, to aid anyone else who had a similar query.
The following allows you to define a specific Domain Controller, which the entire of a script would be able to use... Why might you want to do this when the -server parameter is available to Get-ADUser, New-ADUser, Set-ADObject, etc?
Well I put together a script that creates an AD user, sets multiple properties and creates an exchange mailbox - However, one set of properties revolves around the RDS properties on a 2008 R2 user account, which cannot be set from within New-ADUser. I had to create a function that calls ADSI and uses psbase.invokeSet to update the settings. There is no parameter setting for -server that I'm aware of.
This in itself wouldn't be a big deal, but the script also creates an Exchange mailbox for the user. As my Exchange server is in different AD Site from my workstation, the user account gets created on my local DC, but the mailbox isn't set, because the DC in the same site as the Exchange server hasn't yet received a replicated copy of the new user account.
The solution I found is as follows and is courtesy of http://www.joseph-streeter.com/?p=799
Having loaded import-module activedirectory, you'll have access to AD options in the New-PSDrive commandlet which among everything else allows you to define a new Active Directory Provider to work with.
New-PSDrive -Name <<NameofYourChoice>> -PSProvider ActiveDirectory -Server <<DC Server>> -Root "//RootDSE/" -Scope Global
Once created, you can then change the working Provider with the following command.
CD <<NameofYourChoice>>:
To view the existing list of Providers, type Get-PSDrive. AD is the default Active Directory Provider created when using the ActiveDirectory commandlet. You should also see your newly created Provider.
So for instance if my remote DC is called RemoteDC I would run:
New-PSDrive -Name RemoteAD -PSProvider ActiveDirectory -Server RemoteDC -Root "//RootDSE/" -Scope Global
to create a new Provider called RemoteAD. If I then run:
CD RemoteAD:
All further active directory related commands in the script or the active shell will work with the new Provider RemoteAD. If I would need to change back to my original Provider, I'd simply type
CD AD:
Hope someone finds this useful...
This is what i use:
Get-ADUser -server dcservername.domain.local -identity username