How to use Connect ExchangeOnline -DelegatedOrganization - powershell

I'm trying to build a script where i'm using delegated admin rights. And what I have working is this.
$ConnectionUri = "https://ps.outlook.com/powershell-liveid?DelegatedOrg=$TenantDefaultDomainName"
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Credential $Office365Credentials -Authentication Basic -AllowRedirection
Import-PSSession $Session -AllowClobber
And this is great and connects just fine but my impression is that it's the old way of doing it as some cmdlets just plain don't work with delegation. An example being that I wanted to get the name of the calendar of a user and tried to do so using
Get-MailboxFolderStatistics -Identity $user -FolderScope Calendar
But I get an error on proxy command saying delegated user should be null. So instead I wanted to try using the new cmdlet but could barely find any information about delegation, following the reference here: https://learn.microsoft.com/en-us/powershell/module/exchange/connect-exchangeonline?view=exchange-ps
I came up with this syntax but it doesn't work at all.
Connect-ExchangeOnline -DelegatedOrganization $TenantDefaultDomainName -Credential $MyOffice365PartnerCredentials
Here's the error i'm getting.
New-ExoPSSession : One or more errors occurred.
At C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\2.0.4\netFramework\ExchangeOnlineManagement.psm1:475 char
:30
+ ... PSSession = New-ExoPSSession -ExchangeEnvironmentName $ExchangeEnviro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-ExoPSSession], AggregateException
+ FullyQualifiedErrorId : System.AggregateException,Microsoft.Exchange.Management.ExoPowershellSnapin.NewExoPSSession

I opened an issue on GitHub seeing as this couldn't be the intended behaviour and #chrisda came to my rescue with the response
"this is a shot in the dark, but try using the -UserPrincipalName parameter with Connect-ExchangeOnline:"
Connect-ExchangeOnline -DelegatedOrganization $TenantDefaultDomainName -UserPrincipalName <MyOffice365PartnerUPN>
Mysteriously this works and while using connect-exchangeonline you can use all the normal commands like get-mailboxfolderstatistics that don't work with the old partner method I mentioned first in my question. Hope this helps someone other than me, there is no reference for any of this in the MS documentation or any other place on the internet that I could find.
Reference: https://github.com/MicrosoftDocs/office-docs-powershell/issues/7458

I had this error when there was MFA enabled on the account.

Related

Connecting MFA account to multiple CMDlets

I am trying to connect to three different CMDlets with one login:
$credential = Get-Credential
Connect-MsolService -Credential $credential
Connect-ExchangeOnline -Credential $credential
Connect-AzureAD -Credential $credential
it prompts for login, it prompts for old credentials then prompts for MFA, seems to connect to exchange online but returns the following error:
New-ExoPSSession : One or more errors occurred.
At C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\netFramework\ExchangeOnlineManagement.psm1:475 char:30
+ ... PSSession = New-ExoPSSession -ExchangeEnvironmentName $ExchangeEnviro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-ExoPSSession], AggregateException
+ FullyQualifiedErrorId : System.AggregateException,Microsoft.Exchange.Management.ExoPowershellSnapin.NewExoPSSession
Could I please have assistance to connect these three cmdlets at one please?
Using $credential = Get-Credential, then pass $credential to the commands to login, this way will not work both for Connect-ExchangeOnline and Connect-AzureAD, you just got the error from Connect-ExchangeOnline as the error interrupted the script. For Connect-MsolService, when passing $credential, it will promote you to login interactively again.
In your case, you may need to login for all of them with an MFA-enabled account. If you want to avoid interactively login, you could use Azure AD App to login the commands.
Reference:
App-only authentication for unattended scripts in the EXO V2 module
Using a Service Principal to connect to a directory in PowerShell

Import-module: Could not find a part of the path

I am trying to connect to Exchange Online using PowerShell (As per this documentation) to add distribution group members.
However I am getting the following error:
Import-Module : Could not find a part of the path
'C:\Users\[my user account]\AppData\Local\Temp\tmp_hhw3s30w.xwu\tmp_hhw3s30w.xwu.format.ps1xml'.
At line:3 char:17
+ ... Import-Module -Name $name -Alias * -Function * -Prefix $p ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:String) [Import-Module], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand
My code is as follows:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $adCreds -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking -AllowClobber
Connect-MsolService -Credential $adCreds
My code has worked in the past on my machine, so I am struggling to work out why it is failing now.
Any help would be massively appreciated.
Another thing to try is closing and reopening PowerShell.
For me, I had deleted everything in my local temp folder earlier in the session. It seems PowerShell was using some of what was deleted.
When I reopened PowerShell, it apparently recreated the temp files/directories it needed, and Import-Module worked again.
I know this is an old thread but I had the same issue today. The way I fixed it was to update the module that imports modules, PowerShellGet
To check your current module version, enter: Get-Module -Name PowerShellGet
If you're still on version 1.x.x.x, update it with: Install-Module -Name PowerShellGet -Force -AllowClobber
You may need to close and reopen PowerShell. Be sure to check the version again and compare it with what's available at https://www.powershellgallery.com/packages/PowerShellGet/2.2.5

Office 365 Powershell issue with Set-UserPhoto for anyone other than myself

I'm a global admin for our 365 environment and I'm having an issue with the Set-UserPhoto command in powershell. If I run it for my own username, it works just fine but if I run it using anyone else's username, it errors. Is there some kind of access I need to give myself to make this work? I'm a domain admin and global administrator in 365 so I should be able to do anything.
Connected through PowerShell 3.0 using the following:
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/?proxyMethod=RPS -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session
Command I'm running:
Set-UserPhoto –Identity username -PictureData ([System.IO.File]::ReadAllBytes("C:\userpics\username.jpg"))
Works fine for my username, for any other username I get this:
Error on proxy command 'Set-UserPhoto -Identity:'username' -PictureData: Tons of numbers here that scrolls for quite a while -Confirm:$False' to server BN3PR0201MB1027.namprd02.prod.outlook.com: Server version 15.01.0534.0000, Proxy method
RPS:
The WinRM client cannot process the request. The connection string should be of the form
[://][:][/] where transport is one of "http" or "https". Transport, port and suffix are
optional. The host may be a hostname or an IP address. For IPv6 addresses, enclose the address in brackets - e.g.
"http://[1::2]:80/wsman". Change the connection string and try the request again. .
+ CategoryInfo : NotSpecified: (:) [Set-UserPhoto], CmdletProxyException
+ FullyQualifiedErrorId : Microsoft.Exchange.Configuration.CmdletProxyException,Microsoft.Exchange.Management.Reci
pientTasks.SetUserPhoto
+ PSComputerName : outlook.office365.com
just ran into the exact same problem.
the solution was to run Microsoft Azure Active Directory Module for Windows PowerShell 'as administrator' (Elevated)
as seen here https://www.blackforce.co.uk/2016/09/23/set-userphoto-error-proxy-command
If you are in hybrid mode and thumbnailPhoto property is synched, you can only change the user photo in your local Active Directory and not in Office 365 Exchange PowerShell session.
If you are not in hybrid mode you can try this sample code instead:
Set-UserPhoto "username" -PictureData ([Byte[]] $(Get-Content -Path "C:\userpics\username.jpg" -Encoding Byte -ReadCount 0)) -Confirm:$false
I had the same issue, and solved it from another post (I don't remember which one).
In the connection string:
$LiveCred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri **https://outlook.office365.com/powershell-liveid/?proxymethod=rps** -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session

Invoking-Command for Exchange in Powershell - block is not allowed in a Data section

What I'm trying to do is run this script:
$WPFcmdCreateNewUser.Add_Click({
$ScriptBlockContent = {
param ($first,
$last,
$upn,
$ou,
$password
)
$encryptedpass = ConvertTo-SecureString -AsPlainText $password -Force
New-RemoteMailbox -Name $name -OnPremisesOrganizationalUnit $ou -UserPrincipalName $upn -FirstName $first -LastName $last -Password $encryptedpass -ResetPasswordOnNextLogon $false
}
$ex = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://SERVERNAME/PowerShell/
Invoke-Command -Session $ex -ScriptBlock $ScriptBlockContent -ArgumentList ($WPFtxtNewFirstName.Text, $WPFtxtNewLastName.Text, $WPFtxtNewAlias.Text, $WPFcboNewOU.SelectedItem.Content, $WPFtxtNewPassword.Text)
})
But it's giving me the error:
ERROR: A Begin statement block, Process statement block, or parameter statement is not allowed in a Data section.
ERROR: + CategoryInfo : ParserError: (:) [], ParseException
ERROR: + FullyQualifiedErrorId : InvalidScriptBlockInDataSection
ERROR: + PSComputerName : SERVERNAME
I'm running the whole command from a button click in a XAML Powershell GUI. I googled alot trying to solve the problem as I usually do but no luck :(
Any help would be GREATLY appreciated.
It looks like Exchange uses restricted language mode for remote sessions and you can't execute scriptblocks in your session.
As a security feature, the language mode is obviously controlled at
the server (Exchange), so if you want to enable execution of
scriptblocks you need to interactively logon (RDP or console) to
Exchange and create a new session configuration via
Register-PSSessionConfiguration. You may then connect to Exchange
using this session configuration via New-PSSession -ConfigurationName
and you will then be able to execute scriptblocks by passing this
session instance to Invoke-Command -Session.
Reference:
Remote powershell scriptblock execution question
Bit of an old bump here, but seeing as it is rather high on Google search I figured I could add how I fixed this issue:
$DomainCredential = (Get-Credential)
$fqdn = "<The fully qualified domain name of the target server>"
#Creates a session to the Exchange Remote Management Shell so that we can run Exchange commands. Use https:// if you have a proper setup with certificates. ( Mine was in test env )
$ConfigSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$fqdn/powershell `
-Credential $DomainCredential -Authentication Kerberos
#Imports the module that exists in the session, in this case, Exchange Management -AllowClobber gives the imported commands presedence.
Import-Module (Import-PSSession $ConfigSession -AllowClobber)
This imports the Exchange Commands as you would in a local session. The Exchange commands will still be executed on the remote server. Remember to close the session when done.

Access is Denied when Reset-ComputerMachinePassword is run through Invoke-command

I'm using the following command to reset a remote machine'
s password.
$user="Domain\domainadmin";
$pass="dapassword" | ConvertTo-SecureString -AsPlainText -Force;
$creds=New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $pass;
Invoke-Command -Credential $creds -ComputerName "DomainControllerMachine" -ScriptBlock{
$ComputerName = #"
SomeRemoteHost
"#
Import-Module ActiveDirectory;
Reset-ComputerMachinePassword -Server ${ComputerName};
}
I keep getting 'Access is denied' error.
This command cannot be executed on target computer('DomainControllerMachine') due to following error: Access is
denied.
+ CategoryInfo : InvalidOperation: (DomainControllerMachine:String) [Reset-ComputerMachinePasswor
d], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.ResetCompute
rMachinePasswordCommand
The account I use has all levels of access to the ActiveDirectory. So there won't be a issue with the credentials used for authentication.
If I run the same command on the 'DomainControllerMachine' (logged in as same user) it works fine.
Import-Module ActiveDirectory;
Reset-ComputerMachinePassword -Server "SomeRemoteHost";
Even the whole invoke-command block above just works without complaining on the DomainControllerMachine.
But when I do it remotely through Invoke-Command, or Enter-PSSession I get that dreaded access denied error..
I've also tried using CredSSP after setting up the WSManCredSSP (Client, delegation and Server) on the machines with no luck.
I may have missed something, or is there a better way to handle such a case?
It looks to me like you are running the Reset-computermachinepassword command on the domaincontroller. As far as I know it should be run on the computer that needs to be reset with the DC name in the -server field.
To do this you would need to run the command on the computer that needs it's credentials reset:
Reset-Computermachinepassword -server "DomainControllerMachine" -credential $PScredential
You can try to do it remotely with a PSsession if the computer has powershell remoting enabled. You will need to specify a different authentication method to reach a computer that has lost it's trust with the domain.
You can use Credssp but this will only work if your GPO allows delegating your credentials to the target computer.
Or you can use Basic authentication. But for that to work the Target must accept unencrypted traffic.
The command to do it remotely would probably look something like this:
$session = new-PSSession "targetcomputer" -Authentication Basic -Credential "Domain\domainadmin"
Invoke-Command -Session $session -scriptblock {Reset-Computermachinepassword -server "Domain\domainadmin"}