Connect-MsolService error after importing MSOnline module - powershell

I'm receive the following error when I run Connect-MsolService -
Exception of type 'Microsoft.Online.Administration.Automation.MicrosoftOnlineException' was thrown.
+ CategoryInfo : OperationStopped: (:) [Connect-MsolService], MicrosoftOnlineException
+ FullyQualifiedErrorId : 0x80090345,Microsoft.Online.Administration.Automation.ConnectMsolService
+ PSComputerName : xxxxx
Background -
I am using powershell to manage Active Directory, Exchange and Sharepoint Online user data. I have an SSIS package that dynamically builds arguments passed to powershell scripts for creating new and updating existing AD user data, adding/updating necessary security and distribution groups for each user, enabling exchange mailboxes, and passing custom attribute data to Sharepoint online user profiles.
In effort to maintain the purity of the SQL server running the SSIS package, dynamic sessions are created to servers having the modules necessary for import. This allows me to do all of the things mentioned above without having to install the different modules on my SQL server.
My final hurdle is automating the Office 365 licensing. To script licensing assignments I create a session to our server having the necessary MSOnline module and import it giving me access to the Cmdlets, like Set-MsolUserLicense. However, before I can use the Cmdlets I have to connect to the MSOLService.
When I run Connect-MsolService, the credentials modal pops as expected, the appropriate credentials are entered (which have been verified a thousand times over), and I receive the error shown above.
These commands all work fine when I run them from the server where the MSOnline cmdlets are installed, but return the error when run post successful import-module on my SQL server.
Here are the commands used for establishing the session and importing the MSOnline module -
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $securePassword
$outputSession = $Null
foreach($session in Get-PSSession){
if(($session.ComputerName -eq $Server) -and ($session.Availability -eq "Available")){
$outputSession = $session
}
}
if ($outputSession -eq $Null){
$outputSession = New-PSSession -ComputerName $Server -Credential $cred -Name 'MSOnline'
Invoke-Command -Session $outputSession -ScriptBlock {Import-Module MSOnline}
Import-PSSession -session $outputSession -module MSOnline -AllowClobber
}
Connect-MSOLService is the only Cmdlet giving me an issues using these methods. Any help you can provide will be appreciated.

Sigh. This appears to be a bug with single sign on assistant and MSOL module. I have had this issue reproduced reliably and had it reported to Office 365 support. It went nowhere. To state it simply, Connect-MSOnline works only in local sessions.
Mind you, MSOL module is a very strange beast, it is not using PSSession to maintain connection with Azure but uses some internal mechanisms that must rely on single sign-on assistant. This may be why in remote session MSOL commandlet cannot connect to Azure AD.
It was a dead end for me, and the only way to work around it is to write an application that runs on the server using MSOL module and accepts commands from the client or is invoked on server directly via service or scheduled task.

Related

Permissions required to use Move-VM remotely in Hyper-v 2016

I am attempting to run the PowerShell command "move-vm" remotely but I am getting permissions errors that I can't seem to get past.
My move-vm command looks like this:
move-vm -ComputerName SorceHost -Name $vm.name -DestinationHost $DestHost -IncludeStorage -DestinationStoragePath d:\vms -DestinationCredential $cred -Credential $cred
and I am defining the credentials like this
$username = ".\PSAPIUser"
$password = Get-Content 'C:\key\PSAPIAUTH.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
Both the source and destination are on the same AD domain, and I have created a domain admin account specifically for this function. I have added the domain admins group to the local groups 'Hyper-V administrators' 'administrators' on the source and destination hosts. When I issue the command I get:
move-vm : You do not have the required permission to complete this task. Contact the administrator of the authorization policy for the computer 'SourceHost'.
There are various articles out there about how to do this in 2012, however, its my understanding that the process has changed significantly in 2016 due to the depreciation of something called authorisation manager.
Does anyone have any experience on how to configure permissions to allow remote Hyper-V management with PowerShell specifically in 2016?
Thanks in advance.
Edit:
$cred = Get-Credential
$cred
UserName Password
-------- --------
PSAPIuser#domain.net System.Security.SecureString
move-vm : You do not have the required permission to complete this task. Contact the administrator of the authorization policy for the computer
Managing Hyper-V remotely uses something called Constrained Delegation. Imagine the scenario.
You are on the host Man1, and you are issuing a command to Hyp-001 to move a VM to Hyp-002. So you have Man1 issuing commands to Hyp-001, which is fine as it can use your credentials, but when Hyp-001 passes commands to Hyp-002 it has no credentials to pass, hence you get the error
move-vm : Virtual machine migration operation failed at migration source.
Failed to establish a connection with host 'ng2-vps-011.hyperslice.net': No credentials are available in the security package
to get around this you need to give specific permissions that allows hosts to run specific services on each other, within AD delegation.
From PowerShell it would look like this:
Set-ADObject -Identity $HostDeetsArra.Disname -ADD #{"msDS-AllowedToDelegateTo"="$service1/$Disname","$Service1/$HostName"}
#$disnam = distignushed name, $Service1 is the service 'cifs' $hostanme is the FQDN
In 2016 you also need this:
Set-ADAccountControl -Identity $HostDeetsArra.Disname -TrustedToAuthForDelegation $true
My source for this information is below
https://www.altaro.com/hyper-v/free-powershell-script-configure-constrained-delegation-hyper-v/

Access denied while running Windows Update using Powershell's Invoke-Command

I've been trying to setup a Powershell module that would remotely call Windows/Microsoft update on a server using Invoke-Command, then process the updates, and send everything back to the calling server so it can send an email report.
My issue comes when I try and call the downloader: Powershell seems to be requesting Elevated rights on the remote computer.
Here is a snippet of what I'm trying to run and fail:
Invoke-Command -ComputerName $Server -Credential $Credentials -ScriptBlock {
$UpdateSession = New-Object -ComObject "Microsoft.Update.Session"
Write-Progress -Activity "Updating" -Status "Checking for new updates"
$Criteria = "IsInstalled=0 and Type='Software'"
$Updates = $UpdateSession.CreateUpdateSearcher().Search($Criteria).updates
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $Updates
}
I know the issue isn't with remoting, as the first 4 commands work fine.
The $Credentials variable points to pre-defined credentials, which are Local Admin on the remote server.
When the script gets to the 5th line, $Downloader = $UpdateSession.CreateUpdateDownloader(), I get this error from Powershell:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
+ CategoryInfo : OperationStopped: (:) [], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException
+ PSComputerName : SERVER.sidlee.inc
What could be causing this exactly ?
Thanks in advance for the help!
As i just hit the same wall, and Google isn't of much help either, here is what i could dig up.
For the record, i am pretty much doing the same thing (using custom PS code to check remote systems for Windows Updates) but using WinRM over Python instead of Invoke-Command and also got stuck on Microsoft.Update.Searcher.Search() throwing a E_ACCESSDENIED error.
The UnauthorizedAccessException is indeed not related to Powershell but the underlying API.
I suspect Microsoft started cutting off impersonation in remote session in some recent update (Powershell v5?) as this was (and still is) working just fine on older Windows versions (e.g. Server 2012 with Powershell v3 or 2012 R2 with v4)
To get around this you will need to authenticate (on the remote server) prior to executing your stuff with a PSCredential object.
So Remote Auth -> Local Auth -> Run stuff for example using Start-Process -Credential ...
e.g.
$pass = ConvertTo-SecureString "PA$$W0RD" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential "User", $pass
Start-Process -Credential $creds powershell -ArgumentList "-Command & { ... whatever you want to do ... }"
Keep in mind that this poses a security risk as your password will be parsed in clear text, so don't do this over an
unencrypted channel!

Remote scripting credentials

I've a strange problem that I can't understand. Maybe someone will be able to explain it to me.
I'm trying to automate the installation of an app for SharePoint in a multitenant environment. I run the scripts on a remote machine like this:
$session = New-PSSession -Name "Install App Session" -Authentication Credssp -Credential $InstallAccountCredentials -ComputerName $frontend
$installAppScriptPath = Join-Path $currentScriptPath "\SharePoint\InstallApp.ps1"
$job = Invoke-Command -Session $session -FilePath $installAppScriptPath -ArgumentList $customerUrl, $env:COMPUTERNAME -AsJob
Wait-Job $job
Inside the InstallApp.ps1 I invoke the Import-SPAppPackage command but I get an "Access denied.
You do not have permission to perform this action or access this resource." error. However, if I login to the machine with exactly the same credentials that are used as $InstallAccountCredentials and start the script, everything is working perfectly fine. The account that is used for running this script is an tenant admin account.
Is there something I miss in invoking the command?
PowerShell remote doesn't work for a significant portion of the SharePoint cmdlets. Use the client object model instead - you can invoke those methods from PowerShell as needed.

Executing Powershell script as different User in Exchange 2007 Powershell

My scenario looks like this:
Java opens a Powershell in which Exchange Powershell Command/Scripts should be executed as a different user and the output should be displayed in the Powershell windows that Java opened (so Java can read the output).
So: Normal Powershell --> Add Exchange functionality --> Execute Script/Command as different user
To add Exchange functionality to the normal Powershell I use either
add-pssnapin Microsoft.Exchange.Management.PowerShell.Admin or start Powershell like this C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\bin\exshell.psc1" -command ". 'PathToScript/script1.ps1'"
The problem is the execution as a different user:
runAs (or other tools like PSEXEC or minirunAs) is not working because it opens a new window so the output is not shown in the powershell window opened by Java (an therefore cant be read by Java) and is not suitable for automation
I tried 2 different ways to do it with Powershell:
Way 1:
$username = 'domain\user'
$password = 'Pa$$w0rd'
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList #($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
Invoke-Command -Credential $cred -ComputerName localhost -FilePath PathToScript/script1.ps1
But i get the following Error:
An Active Directory error 0x80072020 occurred while searching for domain controllers in domain MYDOMAIN: An operations error occurred.
+ CategoryInfo : NotSpecified: (0:Int32) [Get-MailboxStatistics], ADTransientException
A simple whoami works this way an prints the user specified in $username but according to this link it looks like that this is not possible with Exchange command (but I dont know how reliable the source is): http://thwack.solarwinds.com/thread/40524
Way 2 (as suggested here http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/f805cbe0-bca9-401a-a381-a7f5520244d2):
$computerName = "localhost"
$username = 'domain\user'
$password = 'Pa$$w0rd'
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList #($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$computerName/powershell -Credential $cred
Import-PSSession $session
But the problem here is that the URI http://$computerName/powershell does not exist (I get WinRM 502 exception) and I dont know how to get a Powershell Virtual Directory on a Server where just the Exchange 2007 Management Tools are installed.
So my questions are: Is there another way to do this? What am I doing wrong in Way 1 & 2 (more how can I add the Powershell VD with Way 2)? Is it possible at all?
I run Java (7 x64) on a WinSrv2012 with Exchange 2007 Management Tools installed. The Exchange Server runs on version 2007. The script is Get-MailboxStatistics -server ExSrv.
This bothers me for nearly a week now so I highly appreciate any help.
I just found out that executing Remote Powershell Commands/Skripts is not supported with Exchange 2007 (http://howexchangeworks.com/2009/11/exchange-2007-sp2-supports-powershell.html). So I need to wait until the upgrade to 2013.
Some workarounds: http://social.technet.microsoft.com/Forums/en-US/exchangesvrgeneral/thread/4596035a-cede-4541-8b8e-e2e9bf1b40dc
Or: http://peerfect.blogspot.co.at/2012/10/re-blog-of-my-exchange-remote.html

Executing a remote SSIS package via Powershell

I'm a Powershell newbie and am trying to use this article to create a way for another user to kick off an SSIS package on a remote server.
The Powershell code I'm using is:
$pass = convertto-securestring "myPassword" -asplaintext -force
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "myUsername",$pass
invoke-command -computername myServer -scriptblock { dtexec.exe /File "d:\myPath.dtsx" } -credential $mycred
Even though I've tried passing my credentials in Powershell, the SSIS package doesn't seem to be executing with them and is executing as an Anonymous user. The package is failing validation for a number of reasons -
The package can not connect to a remote file that requires permission to access (I have permission but the Anonymous User does not). The user that I would like to have run this script does have permission to the folder.
The SQL Server login is failing. I tried forcing a SQL user in the connection details of the package but that doesn't seem to have worked.
Can I use change the Powershell code to use Windows Authentication? How do I execute the SSIS package using those permissions?
you need to enable CredSSP first (see this), and use invoke-command -Authentication Credssp