Pick an account after Connect-MicrosoftTeams - powershell

I'd like to write a PowerShell script which will update Teams members from input list/object. However if I run Connect-MicrosoftTeams command (to authenticate/connect to cloud service) for the first time I am asked to pick an account to use for login. This is an issue since I would like this script to be run as scheduled job. Is there a way how to avoid this when running Connect-MicrosoftTeams command ? Commands I am using:
$credential = Get-Credential
Connect-MicrosoftTeams -Credential $credential
I tried to use "-AccountId "email#address.com" but that didn't help. Of course later I will change Get-Credential to username and encrypted password
EDIT
If I run Connect-MicrosoftTeams -Credential $credential on other computer, where I've never been logged in with my account, instead of "Pick an account" window, I get credential window for username and password:

As commented, this is certainly a dissapointment, but Single-Sign-On cannot be enabled in Microsoft Teams.
See the discussion here

This should achieve what you're trying to do.
Credits to: https://www.jaapbrasser.com/quickly-and-securely-storing-your-credentials-powershell/
Save Credentials
$Credential = Get-Credential
$Credential | Export-CliXml -Path "<File path/name to save credentials"
Connect using saved credentials through MS Teams PowerShell
$Credential = Import-CliXml -Path "<path of exported credential>"
Connect-MicrosoftTeams -AccountId "<email>" -Credential $Credential

For that I always use this from Jaap Brasser:
https://www.jaapbrasser.com/quickly-and-securely-storing-your-credentials-powershell/

At the end I used other module 'AzureAD' and command 'Add-AzureADGroupMember':
# 'password' | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString $Password = "01000000d08c9..." | ConvertTo-SecureString
$Credentials = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "user#domain.com", $Password)
Connect-AzureAD -Credential $Credentials
$AZ_USER=Get-AzureADUser -Filter "UserPrincipalName eq 'user#domain.com'"
$AZ_GROUP=Get-AzureADGroup -Filter "DisplayName eq 'teams_name'"
Add-AzureADGroupMember -ObjectId $AZ_GROUP.ObjectId -RefObjectId $AZ_USER.ObjectId
then I have to wait couple hours until Active Directory and Teams got synchronized and users were added to AD groups / Teams teams. It's not ideal, but it works with saved credentials and with no user interaction.

Related

Powershell script with command Get-CsOnlineUser returning empty LineUri

I am using Powershell script to get users with their Phone number LineUri from Microsoft Teams.
I am using below commands to get the users:
$Password = ConvertTo-SecureString -String "MyPassText" -AsPlainText -Force
$Cred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList "admin#mytenat.onmicrosoft.com", $Password
#Connect to Microsoft Teams
$Conn = Connect-MicrosoftTeams -Credential $Cred -ErrorAction 'Stop'
$UserList = Get-CsOnlineUser | Select-Object UserPrincipalName,LineUri,Identity
Write-Host $UserList
These commands works perfectly fine when I run them one-by-one using the Powershell prompt and I get the user list.
But when I add these commands to Powershell script named get_users.ps1 and run that script from the PS prompt with the same credentials, I get empty LineUri filed.
Please note, the user credentials that I am using is a admin user.
What can be the issue?

Exchange hybrid enviornment powershell add user with a mailbox

What is the best way to add a user in a hybrid on-prem/o365 deployment with a mailbox? If I go into Exchange Admin Center on either the on-prem or o365 and add a recipient it replicates it out to the other EAC as well as adding the user to active directory on prem. Looking thru the powershell documentation it looks like the New-Mailbox command should do that but I cant get it to work. Here is what I have so far.
Connect-ExchangeOnline -Credential $credential -ShowProgress $true
Connect-AzureAD -Credential $credential
Connect-MsolService -Credential $credential
New-Mailbox -MicrosoftOnlineServicesID $uName"#mydomain.com" -Name "$fName $lName" -Password $secureString -ResetPasswordOnNextLogon $true
This creates the mailbox/user in o365 portal but not in on/off-prem EAC or active directory.
Steps:
First Create user and Assign a License
"New-ADUser -Name "user" -Accountpassword (Read-Host -AsSecureString "AccountPassword") -Enabled $true"
Enable remote Mailbox
"Enable-RemoteMailbox user -RemoteRoutingAddress user#domain.mail.onmicrosoft.com"

PowerShell Computer StartUp-Script - Switch user-context?

Through Microsoft Group Policy I did define to run a Powershell-Script on Computer Start-Up. Also I have the requirement to run a Powershell-Script as Scheduled Task without saving credentials.
On both scenarios I have the same problem ...
I want to run a Citrix Powershell-Command (PSSnapIn) like:
Set-BrokerMachine -MachineName "domain.local\$env:COMPUTERNAME" -AdminAddress "RemoteServer.domain.local" -InMaintenanceMode $True
Manual: https://citrix.github.io/delivery-controller-sdk/Broker/Set-BrokerMachine/
Of course only users who have the permission could run those Citrix-commands. I would be able to give a domain-user the permission to run the command "Set-BrokerMachine", but in the mentioned scenarios the PowerShell-scripts run in context of the system-user.
I did simulate the system-user by PSExec:
Error running as System-User
My scripts do other things of course and I want to keep them running as System-User, but now I am looking for a clean solution to get those Citrix-commands running.
If possible, I don't want to save credentials in my scripts.
EDIT #1:
I would be able to workaround with the following code:
$Username = "MySpecialUser"
$Password = 'MyPassword'
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $Username, $SecurePassword
$Result = Invoke-Command -Session ( New-PSSession -ComputerName "RemoteServer.domain.local" -Credential $Credential ) -ScriptBlock {
Add-PSSnapin Citrix*
Set-BrokerMachine -MachineName "domain.local\$args" -InMaintenanceMode $True
} -ArgumentList $env:COMPUTERNAME -HideComputerName
Remove-PSSession -InstanceId $Result.RunspaceId
I don't like this because:
The code has to contain credentials (ofc I could encrypt it ...)
I have to create a permission-system for this special user in Citrix
I have to put the special-user into a local-group on every server, to allow the remote-administration (security-risk)
I don't like to use PSSession
...
Is there a better/cleaner solution? Any ideas?

Add username and password to Powershell script

I'm trying to create a powershell script to allow my kids to reboot my Raspberry Pi from their Windows computer if need be. I've tested everything and have gotten it to work, but the only hitch is that it's prompting for a username and password. I realize the line that's doing it is:
New-SSHSession -ComputerName "myPi" -Credential (Get-Credential)
I've done some searching, but I can't seem to figure out if it's possible to replace the "(Get-Credential)" section to automatically enter the username/password.
And yes, I'm aware of the security risks. They could do much more damage to the Windows machine than they could ever do on the Pi, and the settings on the Pi are very easily restored, so no worries from my end.
Something like this should work:
$user = "someuser"
$pass = ConvertTo-SecureString -String "somepassword" -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
New-SSHSession -ComputerName "myPi" -Credential $creds
You could also call a file that has the password encrypted in it. Note this can only be decrypted by the account it was generated on on the computer it was generated on.
$pass = "Password"
$Username = "Username"
$outfile = "c:\filelocation.xml"
$secureStringPwd = $pass | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($Username,$secureStringPwd)
$credential | Export-CliXml -Path $OutFile
Addressing Bill.
Correct, hard coding the password in the script is bad practice. Below is how I would change the first portion.
The above came from a custom script that's purpose was to create many cred accounts off a input json is why I wrote it that way.
$outfile = "c:\filelocation.xml"
Get-Credential | export-clixml -path $OutFile
You then can call the file in your script like so but this has to be done on the same user and computer that the creds file was generated on.
$Creds = Import-Clixml -Path "c:\file.xml"
New-SSHSession -ComputerName "myPi" -Credential $creds
Good point Edited -argumentlist.
Another option could be to do a 1 time setup with get-credential then convert the password to plaintext using convertfrom-securestring and then in the file you can take your password plaintext secure string and so something similar to the other answers:
$user = "someuser"
$pass = "YOUR LONG PASSWORD GUID FROM ABOVE" | convertTO-securestring
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
New-SSHSession -ComputerName "myPi" -Credential $creds
This lets you do a one time setup, but avoids having multiple files or having your password appear in a readable way in the script.
If you go this way you need to do the setup FROM the account that will run the script ON the machine that will run the script, because it uses those for the encryption as far as I know.

Azure Function calling a Powershell script and unattended login

I'm creating an Azure Function that will call a PowerShell script. In order to do this I need to have the PS script do an unattended login. So I created an application and Service Principal as follows:
# Create an Azure Active Directory Application that will be used for authentication in Powershell Automation scripts.
$Password = ConvertTo-SecureString '<MyPassword>' -AsPlainText -Force
$AzureAdApplication = New-AzureRmADApplication -DisplayName "PowerShellAdminApp" -Password $Password -HomePage "https://www.phoenix.com" -IdentifierUris "https://www.phoenix.com"
# Create the Service Principal
New-AzureRmADServicePrincipal -ApplicationId $AzureAdApplication.ApplicationId
# Add permissions to the Server Principal
New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $AzureAdApplication.ApplicationId.Guid
This all works correctly.
Then, in my PS script(s), I will log in, unattended, as follows:
$Username = "https://www.phoenix.com"
$Password = ConvertTo-SecureString "<MyPassword>" -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $Password
Login-AzureRmAccount -ServicePrincipal -Credential $Credential -TenantId '<MyTenantId'
This works as well. However, I feel like I'm not understanding something or I'm missing something. This is not at all secure. If I have to have this login code in all my PS scripts, I'm basically letting anyone who has access to these scripts see the tenant Id and the password to the app. They then could perform any activity the app can perform.
Am I doing this correctly or not understanding something?
You can use App Settings to define environment variables and store passwords there and in your code just read them:
$username = $env:username
$password = ConvertTo-SecureString $env:password -AsPlainText -Force
Here's how to configure that. https://learn.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings