Powershell remote exchange session missing types - powershell

I'd like to collect and process some data from Exchange on remote server using powershell script. Script will be executed on host A, it will create session to host B, inside this session it will create another session - to exchange endpoint.
I'm doing it this way for security reasons, Exchange session needs to be created locally. The issue is that my first session doesn't have exchange data types, type of my $data object
is PSObject, but it should be MailboxDatabase. Is there a way to somehow import data types needed?
$sessWsman = GetOrCreateSession $ip $login $uri $password $configurationName $retryConnectUsingFdqn $uriTemplate $macroMissingWindowsCredentials $macroUnableConnect $macroSessionsDepleted $macroSessionClosed $null
Invoke-Command -Session $sessWsman -Args #("ENG-AUS-SAM-11") -ScriptBlock {
$sessExchange = GetOrCreateSession $ip $login $uri $password $configurationName $retryConnectUsingFdqn $uriTemplate $macroMissingWindowsCredentials $macroUnableConnect $macroSessionsDepleted $macroSessionClosed $sessWsman
if ( -Not ([bool](Get-Command -Name 'Get-MailboxDatabase' -ErrorAction SilentlyContinue)))
{
Import-PSSession $sessExchange -FormatTypeName * -CommandName Get-MailboxDatabase | Out-null
}
$data = Get-MailboxDatabase -Server $HostName -Status
$data.GetType()
}
I tried adding this Add-PSSnapin Microsoft.Exchange* after importing Get-MailboxDatabase, but it didn't helped.

Related

How to create a sharepoint site collection remotely via powershell?

How to create a new site collection remotely via Powershell
I have tried the following and all failed
Trial one:
# Create a PSCredential Object using the "User" and "Password" parameters that you passed to the job
$SecurePassword = '...............' | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "domain\user", $SecurePassword
$spms = New-PSSession -ComputerName servername -Credential $cred
$Parameters= #{
Session = $spms
ArgumentList ="siteurl","sitename",'domain\user','domain\user2'
ScriptBlock = { Param ($SiteURL,$SiteName,$SiteOwner,$SecondSiteOwner)
Add-PSSnapin Microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
Function Recreate_Site_Collection ($SiteURL,$SiteName,$SiteTemplate,$SiteOwner,$SecondSiteOwner){
# Delete Site Collection
$site = get-spsite -Identity $SiteURL -ErrorAction SilentlyContinue
if($site){
Write-host "Removing the site $SiteURL" -f Red
Remove-SPSite -Identity $SiteURL -Confirm:$false
}
# Create Site Collection
Write-host "creating the site $SiteURL" -f green
echo $SiteOwner
echo $SecondSiteOwner
New-SPSite -Name $SiteName -Url $SiteURL -Template $SiteTemplate -OwnerAlias $SiteOwner -SecondaryOwnerAlias $SecondSiteOwner -Confirm:$false
}
$SiteTemplate = "DEV#0" #Developer Site Template
Recreate_Site_Collection $SiteURL $SiteName $SiteTemplate $SiteOwner $SecondSiteOwner
}}
Invoke-Command #Parameters
Error:
The user cannot be found.
however, if I run the same code on the server with the same variables it goes ok when I run the PowerShell as an admin
Trial two:
# Create a PSCredential Object using the "User" and "Password" parameters that you passed to the job
$SecurePassword = '..........' | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "domain/user", $SecurePassword
$spms = New-PSSession -ComputerName servername -Credential $cred
$Parameters= #{
Session = $spms
ArgumentList = "siteurl","sitename",'domain/user',"1033","DEV#0"
ScriptBlock = { Param ($PortalUrl,$SiteName,$userName,$LCID,$WebTemplate)
$adminSiteUrl = "centraladminurl"
$user = "user"
$pwd = '..............'
$securePwd = ConvertTo-SecureString $pwd -AsPlainText -Force
$cred = New-Object PSCredential($user, $securePwd)
$wsdlUrl = $adminSiteUrl + "/_vti_adm/Admin.asmx?WSDL"
$svc = New-WebServiceProxy -Uri $wsdlUrl -Credential $cred
$svc.Timeout = 300000 # 5 minute timeout
$svc.CreateSite(
$siteUrl, # URL
$siteTitle, # Title
$Description, # Description
$LCID, # LCID 1033 arabic
$WebTemplate, # WebTemplate
$user, # Owner Login
"user", # Owner Name
"mail",
$PortalUrl ,
"portalname"
)}}
Invoke-Command #Parameters
Error:
Exception calling "CreateSite" with "10" argument(s): "Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown."
however, also when running the same script on the server itself with PowerShell run as admin it works with the same variables
please help
I need to automate SharePoint deployment from Jenkins which require a remotely PowerShell script and the main step is creating the site it cannot be established
It's definitely a permissions issue, but it can be kind of a pain to find. My user (the one running the script - probably your Jenkins user) was:
a local admin on the server,
listed in https://sharepointsite/ > Site Settings > Permissions > Site Collection Administrators.
but still got weird errors when running remotely:
# These commands did not work - I'm quoting the errors:
Enter-PSSession -ComputerName MySPServer
Add-PSSnapIn Microsoft.SharePoint.PowerShell
$URI = 'https://MySharePoint.domain.com'
# Can't pipe Site object to Web
Get-SPSite $URI | Get-SPWeb
'Get-SPWeb : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))'
# Can't get SP users using web:
$web = Get-SPWeb $URI
Get-SPUser 'DOMAIN\user' -Web $web
'Get-SPUser : Cannot find an SPWeb object with Id or Url: 7aee0dc1-fe3b-4f9b-bd4b-000000000000 and Site Id: 8b662499-bb26-41ce-978e-000000000000.'
# Can't list properties of a site object
Get-SPSite $URI | fl
'Exception has been thrown by the target of an invocation.'
# Can't create a new site because the user can't be found:
New-SPSite -Url $URI -Name 'Test' -Description 'Test Site' -Template 'DEV#0' -OwnerAlias 'DOMAIN\user'
'New-SPSite : User cannot be found.'
I found that my user was not showing up as a site admin in powershell for some reason. Note that I'm running directly on the server here in order to view the users:
$URI = 'https://MySharePoint.domain.com'
$web = Get-SPWeb $uri
Get-SPUser "$env:USERDOMAIN\$env:USERNAME" -Web $web | Select UserLogin,IsSiteAdmin,IsSiteAuditor,AllowBrowseUserInfo
'UserLogin IsSiteAdmin IsSiteAuditor AllowBrowseUserInfo
--------- ----------- ------------- -------------------
DOMAIN\user False False True'
So I added myself as a site admin for my main site like so:
# Set my user as collection admin:
Get-SPUser 'DOMAIN\User' -Web $web | Set-SPUser -IsSiteCollectionAdmin:$true
# Check permissions again:
Get-SPUser "$env:USERDOMAIN\$env:USERNAME" -Web $web | Select UserLogin,IsSiteAdmin,IsSiteAuditor,AllowBrowseUserInfo
'UserLogin IsSiteAdmin IsSiteAuditor AllowBrowseUserInfo
--------- ----------- ------------- -------------------
DOMAIN\user True True True'
Get-SPSite $uri | fl UserIsSiteAdminInSystem
'UserIsSiteAdminInSystem : True'
And now all of the above commands work normally. It seems like the powershell module for sharepoint requires some access to the main webservice object in order to resolve usernames. I'm not sure what level of access is really required, but this worked for me.

Create a script which disables a Windows Account on a target host. Only Admin can execute this action

I want to create a PowerShell script which will disable the windows account, the target host name will be provided as an argument. Only admin should be able to execute this task.
This is what I have tried. Could someone please tell me if this approach is right or is there any better way to do this.
param( [Parameter(Mandatory=$true)] [String] $TargetHost ,
[Parameter(Mandatory=$true)] [String] $TargetUserName ,
[String] $User ,
[String] $Password)
# Set up a trap to properly exit on terminating exceptions
trap [Exception] {
write-error $("TRAPPED: " + $_)
exit 1
}
function DeactivateAccount($TargetHost , $TargetUserName ,$User , $Password){
$TargetHost = $TargetHost #Target Host on which windows account deactivation will be done.
$TargetUserName = $TargetUserName #User Name of Target.
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() #Domain name of the localhost.
$localHost = [System.Net.Dns]::GetHostName()
$localIP = [System.Net.Dns]::GetHostAddresses("$localHost")
#if TargetHost and LocalHost are same.
if($localHost -like $TargetHost -OR $localIP -like $TargetHost) {
if($Domain -eq [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()){
$process = net user $TargetUsername /domain /active:no #Performs the operation on the domain controller in the computer's primary domain.
} else {
$process = net user $TargetUsername /active:no
}
Write-host " $TargetUsername account deactivated "
}
#If TargetHost is remote Host.
else {
$User = $User #Creds to perform admin function.
$Password = $Password
$SecurePassword = new-Object System.Security.SecureString #Convert password into secure string.
$Password.ToCharArray() | % { $SecurePassword.AppendChar($_) }
$Cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist "$User",$securePassword
$newSession = New-PSSession -ComputerName "$TargetHost" -credential $Cred #Used PSSession for persistent connection and credentials to Specify a user account that has permission to perform this action.
$export_username = Invoke-Command -Session $newSession -ScriptBlock {$username=args[1]} # Invoke-Command command uses the Session parameter(here newSession) to run the commands in same session.
if($Domain -eq [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()){
$process = Invoke-Command -Session $newSession -ScriptBlock {net user $username /domain /active:no}
} else {
$process = Invoke-Command -Session $newSession -ScriptBlock {net user $username /active:no}
}
Write-host " $TargetUsername account deactivated "
Remove-PSSession $newSession # Closes Windows PowerShell sessions.
}
if(-not $?) { # Returns true if last command was successful.
Write-Error "Windows Deactivation Failed!!"
exit 1
}
}
DeactivateAccount($TargetHost , $TargetUserName ,$User , $Password)
Couple of things:
Your meant to show some code to show you tried but since you're new to Powershell I'll let that slide :)
Is it a local windows account you are trying to disable or an AD one? For the purpose of this I'll assume local.
Grab this module: https://gallery.technet.microsoft.com/PowerShell-Module-to-255637a3
The dude basically made a module for exactly what you want to do :)
Note: If you have Powershell 5.1+ you won't need the module they added new cmdlets to do this natively.
Credential-wise I wouldn't worry, Powershell can't bypass windows security, it will execute with the permissions of the user that ran the script unless your script specifically gives credentials for another user in the commands.
Let me know how you get on.

Call a remote script from another with multiple parameters not working

I am trying to create a script that will take input (hardcoded values for now) and call an install PS script and run it on multiple servers. I am using a PSSession and Invoke-Command(see below). The below runs, but does nothing. It doesn't seem to call the other script. Beyond getting it to actually install, I need to know if it was successful or not. I'm pretty novice at Powershell, so any hints/help/suggestions would be great. The below is wrapped in a ForEach to loop the servers with $Computer
Try
{
$session = New-PSSession -ComputerName App02 -Credential $cred
$sourceInstall = $sourceFolder + 'Install\Install.ps1'
Invoke-Command -Session $session -ScriptBlock{param($serviceName, $installFolder, $sourceFolder, $Action, $username, $password) $sourceInstall} -ArgumentList ($ServiceName, $installFolder, $sourceFolder, $Action, $username, $password)
}
Catch
{
$Filename = "Error.txt"
Write-Output "ERROR: Partial Service Deployment. See error log file(s)"
Add-Content $Filename $_.Exception.Message
}
Get-PSSession | Remove-PSSession
You can use it without $Using statement in any version of PowerShell.But pass that too as an argument.
Eg:-
Invoke-Command -ScriptBlock
param($Name)
& $Command $Name
} -ArgumentList 'Get-Process','Notepad'
But you have to pass the arguments positional when using the call operator '&'
Get-Help About_Parameters
https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_parameters
Regards,
Kvprasoon

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}

rdesktop shell escaping issue

I'm trying to send this:
Get-WmiObject Win32_PNPEntity |Where{$_.DeviceID.StartsWith("PCI\VEN_10DE") -or $_.DeviceID.StartsWith("PCI\VEN_1002")}
over rdesktop like:
rdesktop -a8 209.** -u ** -p ** -s "cmd.exe /K powershell.exe Get-WmiObject Win32_PNPEntity |Where{\$_.DeviceID.StartsWith("PCI\VEN_10DE") -or $_.DeviceID.StartsWith("PCI\VEN_1002")}"
But windows' shell says:
'Where{$_.DeviceID.StartsWith' is not recognized as an internal or externa....
What am I doing wrong?
why not using powershell wmi remoting?
$cred = get-credential
Get-WmiObject Win32_PNPEntity -computerName MyRemoteComputerName - credential $cred |Where{$_.DeviceID.StartsWith("PCI\VEN_10DE") -or $_.DeviceID.StartsWith("PCI\VEN_1002")}
-credential are only needed if the actual user running powershell isn't administrator of remote machine.
Hi I needed to do some thing like this once so i wrote some code that can send any ps code to a remote computes and display the results in the ps window on your pc.
Just remember to enable powershell remoting on both pc's.
function remote-pscode ($ServerName,$UserName,$password,$PSCode)
{
$global:RemoteCode = $args[0]
Write-Host $RemoteCode
$conprops = (Get-Host).UI.RawUI
$buffsize = $conprops.BufferSize
$buffsize.Height = 800
$conprops.BufferSize= $buffsize
# Set the user name you would like to use for the connection
$global:RemoteUserName = $UserName
$global:RemoteServerName = $ServerName
# Set the password you would like to use for the connection
# Check to see if you have a file on you drive c:\cred.txt with a password to use in it,if you don't it will create one
# for you and ask you for the password you would like to use
$global:RemotePassword = convertto-securestring $password -AsPlainText -Force
$global:credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $RemoteUserName,$RemotePassword
#Create a connection to the remote computer , put a list of IPAddresses or Computer Names.
$global:session = new-PSSession -ComputerName $RemoteServerName -Credential $credentials
$ScriptBlock = $executioncontext.invokecommand.NewScriptBlock($RemoteCode)
invoke-command -Session $session -ScriptBlock $ScriptBlock
#Close the sessions that where created
$global:closesession = Get-PSSession
Remove-PSSession -Session $closesession
}
remote-pscode -ServerName "NameOfRemotePC" -UserName "UserName" -password "password" -PSCode "any powershell code you want to send to the remote pc"
Several things here: put your PS commands in a script block (or a script). Also, why don't you simply use wmic.exe ?