New-Pssession in runspace does not connect to remote exchange server - powershell

I am trying to import Exchange Server session into runspace.addscript({
it is something like below
$PowerShell = [powershell]::Create()
$PowerShell.RunspacePool = $RunspacePool
#$PowerShell.AddCommand({New-PSSession});
#$PowerShell.AddParameter("ConfigurationName", "Microsoft.Exchange");
#$PowerShell.AddParameter("ConnectionUri","http://win2012-2/PowerShell/");
#$PowerShell.AddParameter("Credential", $ExchangeCredential);
#$PowerShell.AddParameter("Authentication", "Kerberos");
$PowerShell.AddScript({
param($FileName,$FilePath,$i_f)
[console]::WriteLine("script")
$User = "localdomain\administrator"
$Pass = "********"
$ExchangeCredential = New-Object -typename System.Management.Automation.PSCredential -argumentlist $User, $Pass
$ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://win2012-2/PowerShell/ -Authentication Kerberos -Credential $ExchangeCredential
$Session = Import-PSSession $ExchangeSession -AllowClobber
$state = $Session.SessionState
[console]::WriteLine($state) | FT
But i could not get session information from $Session object or $state object,
how can i import the exchange session to runspace script?
any help would be appreciated
Thank you

[console]::WriteLine("foo") does not work inside a runspace, so you don't see any input. You can get around this by passing your current console's details ($host) to your scriptblock
I know you commented them out, but any parameters you're adding should be defined in the param() of your script block
I only have exchange-online, but this should work pretty similarly for either
# example of getting cred once at start
$UserCredential = Get-Credential
# create the PS session and assign a runspace
$PowerShell = [powershell]::Create()
$PowerShell.Runspace = [runspacefactory]::CreateRunspace()
$PowerShell.Runspace.Open()
# First, the script block
$Scriptblock = {
param($cred,$console)
# use $cred defined as a parameter
$ExchSession = New-PSSession -Credential $cred -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Authentication Basic
Import-PSSession $ExchSession -DisableNameChecking -AllowClobber
# test session and output to console
$m = get-mailbox user#domain.com
$console.UI.WriteLine($m.name)
Remove-PSSession $ExchSession
}
# Then add the script block to your runspace
# add Arguments in order, or add named Parameters
$powershell.AddScript($Scriptblock) | out-null
$powershell.AddArgument($UserCredential) | out-null
$powershell.AddArgument($host) | out-null
# run
$invokeInfo = $PowerShell.BeginInvoke()
# wait for completion, check output...
$PowerShell.Runspace.Dispose()
$PowerShell.Dispose()

Related

how can i change the event while closing my powershell gui?

I'm currently working on a powershell gui and i wanted to add a command to the closing event.
While starting the gui, i'm loading a session and i want to close it when leaving.
here is the part of my script:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyle()
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '1300,700'
$Form.Text = "Test close event"
$Form.Add_Closing({
Param($sender,$e)
$result = [System.Windows.Forms.MessageBox]::show(`
"wish to quit?",`
"quit",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
If($result -ne [System.Windows.Forms.DialogResult]::Yes)
{
Get-PSSession |Remove-PSSession
$e.Cancel = $true
}
})
$session = New-PSSession -ConfigurationName Microsoft.exchange -URI "server" -Authentication Kerberos
Import-PSSession $session | Out-Null
... Rest of the script ...
$Form.ShowDialog()
The rest work fine but this part seems to pose problem.
If someone has an idea i'm interested.
If I understood correctly, your form on closing displays the "wish to quit?" question successfully, then it successfully executes Get-PSSession | Remove-PSSession. But once all finished you see your Exchange connection is still active.
If that's the case, the following approach should work - use "script:" scope for your $session variable.
code fragments:
$script:session = New-PSSession -ConfigurationName Microsoft.exchange -URI "server" -Authentication Kerberos
Import-PSSession $script:session | Out-Null
Remove-PSSession $script:session
Full code:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyle()
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '1300,700'
$Form.Text = "Test close event"
$Form.Add_Closing({
Param($sender,$e)
$result = [System.Windows.Forms.MessageBox]::show(`
"wish to quit?",`
"quit",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
If($result -ne [System.Windows.Forms.DialogResult]::Yes)
{
Remove-PSSession $script:session
$e.Cancel = $true
}
})
$script:session = New-PSSession -ConfigurationName Microsoft.exchange -URI "server" -Authentication Kerberos
Import-PSSession $script:session | Out-Null
... Rest of the script ...
$Form.ShowDialog()
Note Since we are referencing session variable using "script:" prefix, you shall save your code in *.ps1 file and run it as a script, e.g. PS> C:\scripts\myscript.ps1
Reference:
about_Scopes

How can I connect to Exchange online (connect-exopssession) with credentials and no form?

I've tried a couple of variants of this (all 3 shown below). With this code, if I specify a value for -UserPrincipalName a form will pop up quickly and disappear, fast enough to where only the form borders are rendered. If I do not specify a value for -UserPrincipalName, that same form opens and asks for me to sign in with my email address. The third option I tried was with -Credential and a credential object, I get the error:
"New-ExoPSSession : missing_federation_metadata_url: Federation Metadata Url is missing for federated user. This user type is
unsupported." .
My end goal here is to authenticate without the form popping up so I can run some code with a scheduled task, which right now will not work because of the form and interactive mode. I can use creds, NO MFA and need to supress this form
somehow.
How can I connect to Exchange Online without this form appearing? Is there a way to use New-PSsession or Import-PSsession, or to wrap the New-ExoPSSession in something that prevents it from opening a form?
(Also, we need an "exchange-online" tag added, I don't have enough reputation to do so)
[string] $ConnectionUri = "https://outlook.office365.com/PowerShell-LiveId"
[string] $AzureADAuthorizationEndpointUri = 'https://login.windows.net/common'
[System.Management.Automation.Remoting.PSSessionOption] $PSSessionOption = $null
[switch] $BypassMailboxAnchoring = $false
[string] $DelegatedOrganization = ''
$PSSession = New-ExoPSSession -UserPrincipalName "xxx#xxx.xxx" -ConnectionUri $ConnectionUri -AzureADAuthorizationEndpointUri $AzureADAuthorizationEndpointUri -PSSessionOption $PSSessionOption -BypassMailboxAnchoring:$BypassMailboxAnchoring -DelegatedOrg $DelegatedOrganization
$PSSession = New-ExoPSSession -ConnectionUri $ConnectionUri -AzureADAuthorizationEndpointUri $AzureADAuthorizationEndpointUri -PSSessionOption $PSSessionOption -BypassMailboxAnchoring:$BypassMailboxAnchoring -DelegatedOrg $DelegatedOrganization
$user = "xxx#xxx.xxx";
$password = ConvertTo-SecureString "xxxx" -AsPlainText -Force;
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList ($user, $password)
$PSSession = New-ExoPSSession -UserPrincipalName "xxx#xxx.xxx" -ConnectionUri $ConnectionUri -AzureADAuthorizationEndpointUri $AzureADAuthorizationEndpointUri -Credential $creds -PSSessionOption $PSSessionOption -BypassMailboxAnchoring:$BypassMailboxAnchoring -DelegatedOrg $DelegatedOrganization

unexpected token in expression or statement - powershell

## To run the script
# .\get_status.ps1 -Hostname <host> -Service_Action <action> -Service_Name <name>
#$Hostname = "hostname"
#$Service_Action = "Get-Service"
#$Service_Name = "service_name"
param(
[string]$Hostname,
[string]$Service_Action,
[string]$Service_Name
)
$ScriptBlockContent = {
param($Service_Action, $Service_Name)
& $Service_Action $Service_Name
}
# user credentials
$Username = "username"
$Password = "password"
# To avoid Manual entry of Username and Password
$Secure_String = convertto-securestring $Password -asplaintext -force
$User_cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $Secure_String
# Create a Session
$pso = New-PSSessionOption -NoMachineProfile
$sess = New-PSSession -ComputerName $Hostname -SessionOption $pso -credential $User_cred
#Run a powershell script in the session.
Invoke-Command -Session $sess -ScriptBlock $ScriptBlockContent -ArgumentList $Service_Action, $Service_Name
# Remove session
Remove-PSSession $sess
To run the script:
.\<script_name>.ps1 -Hostname <host> -Service_Action <action> -Service_Name <name>
For ex: Service Action is- Get-Service, Stop-Service, Start-Service
and then Name
Command: Get-Service Servicename
I am getting an error:
Unexpected token in expression or statement on this line of code:
$ScriptBlockContent = {
param($Service_Action, $Service_Name)
$Service_Action $Service_Name # here is the error
}
You are passing your commands as strings to your function, so what you are syntactically doing with $Service_Action $Service_Name is to refer to two string objects in one line without any operator connecting them. That is the reason for the exception.
To tell powershell, that you want to execute a string as a command you have several options:
One option is to pass the commands as a single string to the Invoke-Expressioncmdlet:
Invoke-Expression "$Service_Action $Service_Name"
Alternatively you can use the call-Operator &, which also tells powershell to treat a command as string. In this case you cannot give cmdlet and arguments in a single string, but in two:
& $Service_Action $Service_Name
## To run the script
# .\get_status.ps1 -Hostname <host> -Service_Action <action> -Service_Name <name>
#$Hostname = "hostname"
#$Service_Action = "Get-Service"
#$Service_Name = "service_name"
param(
[string]$Hostname,
[string]$Service_Action,
[string]$Service_Name
)
$ScriptBlockContent = {
param($Service_Action, $Service_Name)
& $Service_Action $Service_Name
}
# user credentials
$Username = "username"
$Password = "password"
# To avoid Manual entry of Username and Password
$Secure_String = convertto-securestring $Password -asplaintext -force
$User_cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $Secure_String
# Create a Session
$pso = New-PSSessionOption -NoMachineProfile
$sess = New-PSSession -ComputerName $Hostname -SessionOption $pso -credential $User_cred
#Run a powershell script in the session.
Invoke-Command -Session $sess -ScriptBlock $ScriptBlockContent -ArgumentList $Service_Action, $Service_Name
# Remove session
Remove-PSSession $sess`enter code here`

Enter-Pssession not working

I have to machines in same network one with windows7 and another win windows server 2012.I tried Enter-PSsession on windows7 machine from server2012 machine...
$ComputerName = "windows7-PC"
$username="administrator"
$password="password"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cr = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
Invoke-Command -Session $Session -ScriptBlock { echo '1' }
On doing same,i got an error
New-PSSession : [windows7-PC] Connecting to remote server windows7-PC failed with the following error message : Access is denied.
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an
argument that is not null or empty, and then try the command again.
using same script i m able to execute 'echo 1' from windows7-pc to server2012-pc but not from server2012-pc to windows7-pc.
You need to add the remote server in trusted domain.
Please follow below article:
https://technet.microsoft.com/en-us/magazine/ff700227.aspx
This will surely help you.

Variable values to pass from local computer to remote in Pssession

I have a powershell script. Executing this will create a session with remote computer and execute some scriptblock inside remote computer. After that execution I need to send a mail.
So, I get the arguments required (like from, to, subject, body, smtp server, credentials) etc locally as shown below:
$param = #{
SmtpServer = 'SMTPServer'
Port = 587
UseSsl = $true
Credential = $crede
From = 'server#domain.in'
To = 'userv#domain.in'
Subject = 'Hi'
Body = "Hello"
}
$crede has value (username explicitly given, password reading from a text file).
And I call that param as shown below:
Send-MailMessage $using:param
This is inside an Invoke-Command.
But when I run this program it asks me for the mail message details like from, to, smtp server etc.. Please note that these values are given on $param locally. I guess $param values are not being passed to the remote session.
Can someone please support me. Any help would be really appreciated.
I just had a similar issue.
$processName = myProcess.exe
$session = New-PSSession -ComputerName $anycomputer -Credential $credentials
# powershell syntax requires -Scriptblock and { on this line
Invoke-Command -Session $session -ScriptBlock {
param([string] $processName)
Get-Process -Name $processName
} -Args $processName
Remove-PSSession $session
$processName = myProcess.exe
$session = New-PSSession -ComputerName $anycomputer -Credential $credentials
Invoke-Command -Session $session {Get-Process -Name $using:processName}