Run Exchange command from Windows Powershell - powershell

I've connected to EMS from Windows Powershell using the below:
&"C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1 "
I can't run Get-ExCommands or Disable-Mailbox -Identity Test without getting an error. "The term Get-ExCommands is not recognized as the name of a cmdlet, function, script..."
Is it possible to run Exchange commands in Win Powershell?

This works fine for me:
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
If you did not install the Exchange Management Tools on the server you are using you can connect to exchange this way:
$s = New-PSSession -ConnectionUri http://putyourservernamehere/Powershell -ConfigurationName Microsoft.Exchange
import-pssession $s

I suspect you need to import the Exchange PowerShell module. Take a look at this:
Exchange Powershell - How to invoke Exchange 2010 module from inside script?

Related

When using a function within a Powershell module, a psm1, is it possible to export the ExchangeOnline functions to be accessible in the console?

Working on several Powershell functions which connect to Office365 services and automate many of my usual tasks. Found when I have the function in a psm1, running the function to connect to ExchangeOnline the functions are not exposed to the console and only functions within the same module.
While I know I can export-modulemember, this only works for functions when the module is loaded, happens well before I connect-office365 -exchangeonline.
Is there anyway to export the commands loaded when connecting to Office 365 after connecting?
By placing the following function in a psm1 instead of a ps1 and loading it, and then running connect-off365 -exchangeonline, all Exchange Online related commands are not usable in the console. Yet, having the same function in a ps1 and loading it, the ExchangeOnline functions work.
Function Connect-Office365 {
Param(
[Switch]$ExchangeOnline,
[Switch]$EO
)
if ($EO) { $ExchangeOnline = $true }
elseif ($EO -and $ExchangeOnline) { Write-Warning "No need to declare ExchangeOnline and EO" }
$Credential = Get-Credential -message "Enter Office 365 credentials,`r`nor cancel to not connect to Office 365"
if ($null -eq $Credential) { Write-Host "Skipped entering credentials"; $TryAgain = $False }
if ($ExchangeOnline) {
Write-Host "Connecting to Exchange Online Services"
$global:ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection -EA stop
Import-PSSession $global:ExchangeSession -AllowClobber -DisableNameChecking
}
}
For example
PS C:\Users\TechWithAHammer> import-module C:\scripts\Connect-Office365.psm1
PS C:\Users\TechWithAHammer> connect-office365 -eo Connecting to MSOL Services Connecting to Exchange Online Services
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0 tmp_3zvdxnnc.gd0 {Add-AvailabilityAddressSpace, Add-DistributionGroupMember...
PS C:\Users\TechWithAHammer> get-mailbox
get-mailbox : The term 'get-mailbox' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ get-mailbox
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (get-mailbox:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
As per the answer in Commands from implicit remoting module not available when created from another module's function, found that I had to use Import-Module to import the Exchange Online and Compliance and Security center modules into the global session.
Import-Module (Import-PSSession $global:ExchangeSession -AllowClobber -DisableNameChecking) -Global

Using invoke-command scriptblock with exchange management shell

I've written some scripts to automate some user add and user modifications functions. But there is one last piece to the puzzle I can't figure out.
I need to run some commands in exchange management shell on the exchange server from a local powershell session, like an invoke-command scriptblock.
Is this possible?
Will adding Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
to the beginning of my script block accomplish this?
As for this...
Will adding Add-PSSnapin
Microsoft.Exchange.Management.PowerShell.SnapIn
You can't do this natively, without installing the EMC directly on your host.
Secondly, there is no real reason to. You can use PSRemoting to proxy the Exchange cmdlets to your host. The cmdlets are only available during the session
This process is the same whether you are using Exchange on-prem or Exchange online, though Exchange Online points to the O365 URI.
This has been documented in several places via the MS provided docs as noted here:
Connect to Exchange servers using remote PowerShell
Connect to a remote Exchange server
1.On your local computer, open Windows PowerShell, and run the following command:
$UserCredential = Get-Credential
In the Windows PowerShell Credential Request dialog box that opens, enter your user principal name (UPN) (for example, chris#contoso.com) and password, and then click OK.
2.Replace with the fully qualified domain name of your Exchange server (for example, mailbox01.contoso.com) and run the following command:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN>/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Note: The ConnectionUri value is http, not https.
3.Run the following command:
Import-PSSession $Session -DisableNameChecking
https://learn.microsoft.com/en-us/powershell/exchange/exchange-server/connect-to-exchange-servers-using-remote-powershell?view=exchange-ps
Remote PowerShell in Exchange 2013
1.On your local computer, open Windows PowerShell and execute the following command:
$UserCredential = Get-Credential
2.After entering the credentials prompted when you executed the above command, execute the following:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<FQDN of Exchange 2013 Client Access server>/PowerShell/ -Authentication Kerberos -Credential $UserCredential
3.Finally, import the session established above with the following:
Import-PSSession $Session
https://blogs.technet.microsoft.com/nathanscott/2015/06/14/remote-powershell-in-exchange-2013/
Yes you can, some commands have to be run locally, below is an example. You can do the same with Exchange.
Invoke-Command -ComputerName $srv -ScriptBlock{Add-PSSnapin Microsoft.Forefront.Filtering.Management.Powershell;
Get-EngineUpdateInformation}

New-MailboxExportRequest error when running from CMD

I have a very simple PowerShell script that runs the new-mailboxexportrequest command. if I run the script as a scheduled task, I get the following error:
new-mailboxexportrequest : Failed to communicate with the mailbox database.
If I open the PowerShell command prompt, and run the script, I get the same error.
The script only works when I manually open the exchange management shell and run the script.
Keep in mind that the first line of the script actually has the exchange snapin command:
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010
The question is, what loads from the exchange management shell that doesn't load on when the snapin runs?
Also, the scheduled task, the manual powershell command and the exchange management shell commands are running on the same box (exchange server). I'm also running them with the same user account.
Any help is appreciated.
the reason for your problem is explained in this link:
https://blogs.technet.microsoft.com/rmilne/2015/01/28/directly-loading-exchange-2010-or-2013-snapin-is-not-supported/
this should fix your problem :
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN>/PowerShell/ -Authentication Kerberos
Import-PSSession $Session
you can check this also :
powershell -psconsolefile "C:\Program Files\Microsoft\Exchange Server\Bin\exshell.psc1" your-exchange-command

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

Running batch file on Remote Computers using PowerShell 2.0

I am trying to run a exe on remote machines which would basically uninstall a product agent. below is the code:
$test = Get-Content PC.txt
foreach ($a in $test)
{
$curr = Get-Location
Set-Location \\$a\Admin$\System32\CCMSetup
.\ccmsetup.exe /uninstall
Set-Location $curr
}
It doesn't work. I ended up removing the program from the host computer itself :)
Alternate Option: I created a batch file with the command line:
cd C:\Windows\System32\ccmsetup
ccmsetup /uninstall
exit
It seems the above can also be achieved using Invoke-Command.
Invoke-Command -ComputerName $client -FilePath UninstallCCM.cmd
Apparently, it does not accept batch file. I would like to keep it as simple as possible.
Currently I am using PSExec for installing and uninstalling the program. Do I need to enable PS Remoting (WinRM) on every remote machine on whom I need to execute scripts using PowerShell?
Can someone please help? Thanks in advance.
This command should execute successfully:
Invoke-Command -ComputerName $client -ScriptBlock { cd C:\Windows\System32\ccmsetup; ccmsetup /uninstall} -Credential $(Get-Credential) -Authentication CredSSP
but you will need to enable CredSSP authentication on all machines by running these two commands on each machine:
Enable-WsManCredSSP -Role Server -Force
Enable-WSManCredSSP -Role Client -DelegateComputer * -Force
I highly recommend downloading PSTools. There is a command in there called "psexec"
PSexec is so simple, you call it like this:
psexec \\myserver C:\Windows\System32\ccmsetup /uninstall