Login-AzureRmAccount can't login to Azure using PSCredential - powershell

I'm trying to login to my Azure account non-interactively from a script.
I just don't know why it fails:
$secpasswd = ConvertTo-SecureString "P#$$W0rd" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("script1234#outlook.com", $secpasswd)
Login-AzureRmAccount -Credential $cred
This is the error I am getting:
Login-AzureRmAccount : Sequence contains no elements
Could anyone help me with this one please?
Thanks

Atf's answer has a point but however, this is not only the issue. We cannot directly sign in non-interactively using Hotmail or Outlook account. You must use domain of your account to sign in.
See a similar issue posted in server fault : https://serverfault.com/questions/746557/add-azureaccount-unknown-user-type-unknown-user-type-on-azure-automation/746673
It mentions:
Make sure the credential asset name (not username) is a simple string.
Also make sure the credential asset username is a valid OrgID user
(ex: abc#fdgdf.onmicrosoft.com), not a Microsoft / Live account
(joe#gmail.com).

You are facing issue with the '$' character in your password P#$$W0rd
You need to introduce escape character (`) in order to retain the exact value. See the difference-
Hence your code look like this-
You can have a look in escape characters in powershell here - http://ss64.com/ps/syntax-esc.html

Related

Execute an App registration without AzureAD

For a professional project, a chunk of the pipeline must be able to create an application (the first App registration, so I only have a global Admin) automatically within Azure AD. So far I used AzureAD which works well with Powershell 5.6 on Windows.
I now must be able to run the code with Ubuntu 20.04 and its Powershell 7.2. Unfortunately for me, AzureAD module is only supported on non-core Windows PowerShell, therefore it does not work on core PS6 or PS7. A very simplified piece of code is the following:
# Connection infos
$tenantId = "abcdef12345-1234-1234-124-abcdef12346789"
$account = "my_admin#domain.com" # Is cloud Admin by default
$password = ConvertTo-SecureString "MyPassword" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($account, $password)
Connect-AzureAD -Credential $psCred -Tenant $tenantId
# Create app
$appName = "MyApp"
New-App -appName $appName -tenant_id $tenantId
I am stuck and my question is the following: how could I run such an operation with Powershell 7.2 considering AzureAD is not usable? I did check Connect-MgGraph for the connection part only (https://github.com/microsoftgraph/msgraph-sdk-powershell) but the clientId is an infos that I don't have -and want to create-.
Thanks in advance
You can use DeviceLogin as explained in this article to obtain an oAuth access token for you Global Administrator account in PowerShell (independent of the version) but this first step needs a human interaction.
After obtaining the token, you can use it to make Graph API calls with your Global Administrator permissions to create an application.
Once you create your first application, you must attribute required permissions and use it to automate the process (obtain token programmatically using API calls) for application creation in PowerShell.
You could use Resource Owner Password Credentials (ROPC) to authenticate, however Microsoft actively discourages it in their documentation due to the security implications of sending a password over the wire.
If the security issues present with this method of authentication are still tolerated within your acceptance criteria, you would still need a ClientID. Luckily, AzureAD has a well-known ClientID that you can use to authenticate. This ID is 1950a258-227b-4e31-a9cf-717495945fc2
The below Powershell code should get you started. I've basically translated the HTTP request within Microsoft's documentation into a splatted Invoke-RestMethod command.
$LoginWithROPCParameters = #{
URI = "https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/token"
Method = "POST"
Body = #{
client_id = "1950a258-227b-4e31-a9cf-717495945fc2"
scope = "user.read openid profile offline_access"
username = "username#contoso.onmicrosoft.com"
password = "hunter2"
grant_type = "password"
}
}
Invoke-RestMethod #LoginWithROPCParameters

Powershell setting new local users forced password change

Afternoon folks,
I've got a quick question. I'm making a script to make local user accounts based off a csv file. I have it all working no problem using the New-LocalUser command. What I am curious about is there a parameter string I can add or anything to have it so the user Has to change the password upon first login?
I've looked through https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/new-localuser?view=powershell-5.1 I just was wondering if there was something I've missed.
You haven't. Most of the time, when cmdlets are released, they don't include all functionality for a particular technology (e.g. Get-Service versus Win32_Service). In this case, New-LocalUser, Get-LocalUser, Set-LocalUser are in this boat.
However, in order to achieve what you're after, the WinNT provider has exposed this functionality for a long time:
$u = New-LocalUser -Name test -Password ('123456789' | ConvertTo-SecureString -AsPlainText -Force)
$WinNt = [adsi]"WinNT://localhost/$($u.Name)"
$WinNt.PasswordExpired = 1
$WinNt.SetInfo()

Teams PowerShell: Access token validation failure

I am trying to create a team with the new Teams Powershell. Looks like everything is working, until I try to use my service account instead of my own.
The code below is working, if I replace the $credential line and use my own credentials. If I use the automation account, then I got this:
New-Team : Error occurred while executing
Code: InvalidAuthenticationToken
Message: Access token validation failure.
I tried searching for this error message, but I only found Graph API samples, that happen behind the scenes of the Teams PowerShell. I also tried other scripts, like PnP, they all work fine with the same automation account. Is this a bug in the Teams API self or can I do something on my side?
$credential = Get-AutomationPSCredential -Name 'provisioning'
$connection = Connect-MicrosoftTeams -Credential $credential
$t = Get-Team -DisplayName "TEST"
Assuming your service account has proper privileges to create channel.
Reference: https://learn.microsoft.com/en-us/graph/api/team-put-teams?view=graph-rest-1.0
If you reckon you have proper privileges to create teams and channels then make sure you give full scope to the service account
Connect-PnPOnline -Scopes "Group.ReadWrite.All"
Hope it will give you some idea to solve the error. Thanks

Prevent PowerShell script from being read

I have the below PowerShell script (myscript.ps1) in which I ask for username and password. Depending on the username and password it copies a file to a certain destination.
$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ Copy-Item "test1.pdf" "\test\test1.pdf"; }
else
{ Copy-Item "test2.pdf" "\test\test2.pdf"; }
Requirement: I want to make this file protected so no one can edit it and see the username and password.
PS2EXE
I found a solution found here which converts the PowerShell script to an .exe file. When I originally run the script using PowerShell a dialog box appears allowing me to enter the username and password:
After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"
I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?
Q: Why does the EXE prompt with "Credential"?
This isn't an answer to the real question, and is based on guessing/supposition about PS2EXE, but I hope it is useful to clear up some confusion.
Having looked briefly at the PS2EXE page linked above, it seems that this utility encodes the script in Base64 and bundles it with a lightweight (?) custom PowerShell host. When run, I suppose the EXE starts the host, decodes the script and runs it.
The problem is that the Get-Credential cmdlet is running within a PS host that probably can't interact with the desktop. That is, it can't put up the GUI prompt for credentials. It therefore needs to prompt for the Credential property on the command line, explaining why you see that behaviour.
Workaround with Read-Host?
Instead of trying to use Get-Credential to prompt for username and password, you could embrace what PS2EXE seems to be doing and just use Read-Host:
$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString
$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ ... }
Using -AsSecureString will hide the password on the screen. The $Password variable will be of type System.Security.SecureString, which can be used to create a PSCredential object as shown.
You'd need to test this, but it seems that you're able to read from the shell but not from a GUI prompt.
And just to be clear: none of this is anywhere near best-practice security. If you need authentication/authorization for these activities, step back and look at the problem again.
Workaround with two scripts?
It seems that PS2EXE doesn't support -AsSecureString in the same way that normal PowerShell does, i.e. it doesn't hide the characters. A possible workaround for this would be to collect the username and password from the user in one script and then pass them to a PS2EXE-converted script for processing.
Launch-MyScript.ps1:
$Credentials = Get-Credential
& MyScript.exe $Credentials.Username $Credentials.Password
MyScript.exe (coverted with PS2EXE):
param($Username,$Password)
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
if ($Credentials.Username -eq "user1" -and
$Credentials.GetNetworkCredential().password -eq "pass1")
{
...
}
The user runs Launch-MyScript.ps1 and completes the password prompt. Then the EXE is run automatically with the username and password passed in as arguments. Note that, as shown above, the password is a Secure String. Test this; I'm not using PS2EXE so it's a theoretical solution at the moment.
If you can't pass $Password along the pipeline as a Secure String object, you can convert it to text with ConvertFrom-SecureString in the first script, then conver it back with ConvertTo-SecureString in the second one.
According to this article http://windowsitpro.com/powershell/protect-your-powershell-scripts you should first set ur execution policy to AllSigned by Set-ExecutionPolicy AllSigned, then create a certificate using makecert cmdlet.
Then u can sign single script using Set-AuthenticodeSignature cmdlet or use .pfx File to Sign a Script which appears even safer.
Hope it helps a bit.

Creating file in a user context in powershell

I am trying to create a file using powershell in a specific user context. E.g I have a user user01 on my local machine and I want to create a file in its context.
I am doing something like
New-Item c:\file.txt -Credential User01
It works but prompts me for password which I dont want it to. Is there any way I can accomplish this without having it prompt for password ?
The credential parameter on new-item is not actually supported for filesystems, so I'm not sure what you mean by "it works." It does NOT create the file as the passed user. In fact, the filesystem provider will say:
"The provider does not support the use of credentials. Perform the operation again without specifying credentials."
Taking an educated guess, I'd say you're trying to create a file with a different owner. PowerShell cannot do this on its own, so you'll need the following non-trivial script:
http://cosmoskey.blogspot.com/2010/07/setting-owner-on-acl-in-powershell.html
It works by enabling the SeBackup privilege for your security token (but you must already be an administrator.) This allows you to set any arbitrary owner on a file. Normally you can only change owner to administrators or your own account.
Oh, and this script is for powershell 2.0 only.
Rather than use a PowerShell cmdlet or .NET scripting on this one, you might take a look at the Windows utility takeown.exe. However, even it requires you supply the user's password that you're assigning ownership to.
Ok, I do start process in the user context and then create a file. Works like a charm.
Password, FilePath and UserName are passed in as arguments from command line.
$pw = convertto-securestring "$Password" -asplaintext –force
$credential = new-object -typename system.management.automation.pscredential -argumentlist "-default-",$pw
$localArgs = "/c echo>$FilePath"
[System.Diagnostics.Process]::Start("cmd", $localArgs, "$UserName", $credential.Password, "$Computer")
Or just make a call to SUBINACL.EXE? No need for password then.