How to get local computer name after New-PSSession -Computername? - powershell

I am getting the below error, please advise how to fix this error for null-valued expression
You cannnot call a method on a null-valued expression
+CategoryInfo : InvalidOoperation: (:)[], RuntimeException
+FullyQualifiedErrorId: InvokeMethodonNull
+PSComputerName: DC1
Code below
function myfunction (){
$remoteserver = 'DC1'
$Session = New-PSSession -Computername $remoteserver -Credential $Cred
Import-Module ActiveDirectory
$local= $env:COMPUTERNAME
Invoke-Command -ComputerName $remoteserver -Credential $cred -ScriptBlock
{$using:local
if($local.substring(5,3) -imatch "Sys") {
Get-ADComputer $local | Move-ADObject -Targetpath "ou=PRD,ou=Servers,dc=com,dc=Companycorp,dc=net"}
}
} #end function
Invoke-Command -ComputerName $remoteserver -ScriptBlock ${Function:myFunction}

What you're looking for is the $using: scope. If you define variables that you want to use in your remote execution, you need to access them like:
$PC = $env:ComputerName
Invoke-Command -Computer DC01 -ScriptBlock { $using:PC <# logic #> }
If you mean you want to remote into DC01 to run commands against localhost, you're going to run into the second-hop problem due to Kerberos.
Update: Your new example looks pretty convoluted. Here's an example that should work:
$MyPC = $env:ComputerName
$Session = New-PSSession -Credential (Get-Credential) -ComputerName 'DC1'
Invoke-Command -Session $Session -ScriptBlock {
Import-Module -Name 'ActiveDirectory'
$PC = $using:MyPC
If ($PC.Substring(5,3) -eq 'sys')
{
Get-ADComputer -Identity $PC |
Move-ADObject -TargetPath 'ou=PRD,ou=Servers,dc=com,dc=Companycorp,dc=net'
}
}

What I think you're asking is 'how do I open a session on a remote pc, but then still run commands on my local PC'. If that's so, then let's walk through it.
First, we can open a remote connection to another computer in PowerShell by creating a new PSSession, as you're doing here:
$session = New-PSSession -Computername DC01 -Credential $cred
You can then either step into the remote computer wholly using Enter-PSSession, or just send individual commands to the remote computer using:
Invoke-Command -ScriptBlock {#Commands to run on the remote PC}`
-Session $session
Once you enter the remote PC, you can return to your own PC using the Exit-PSSession command.
#Enter Remote PC
Enter-PSSession $session
DC01> hostname
*DC01*
#Step out of Remote PC
Exit-PSSession
PS> hostname
*YOURPCNAME*
If this isn't what you want to do, let me know and we'll get you sorted.

You have to use Invoke-Command :
$session = New-PSSession -Computername DC01 -Credential $cred
Invoke-Command -Session $session -ScriptBlock {
$remoteComputerName = $env:computername
}

Related

PowerShell cmdlet get-service returns different results remotely

If I run the following command remotely from a server it returns a list of 37 services.
get-service -computername <computer name>
If I connect to the remote host and run the same command through a remote session it returns a list of 161 services.
new-pssession <computer-mame>
enter-pssession <session id>
get-service
can anybody point to me to an explanation please?
I cannot reproduce your result. Try the following snippets:
$ComputerName = 'ComputerName'
$ServiceList = Get-Service -ComputerName $ComputerName
$ServiceList.count
$PSSession = New-PSSession -ComputerName $ComputerName
Invoke-Command -Session $PSSession -ScriptBlock {
$ServiceList = Get-Service
$ServiceList.count
}
Try Invoking the command on the remote computer and storing the results in a Variable
$remoteCommputer = "RemoteComputerName"
$GetServiceData = (invoke-command -ComputerName $remoteCommputer -ScriptBlock { get-service })

Sending out lockdown or general message to all active users in domain, cross-architecture

I'm trying to setup a script which will message all users in domain - Mixture, some are on Windows 10 Surface Pro's, some Citrix VDI.
The Citrix Part at the bottom isnt quite right, when starting a session, i seem to need to import the Citrix modules to the DDC, even though i'm connect via a PS Session (new-pssession) to the controller. The message on the VDI users desktop isn't appearing and, not sure why...
$Cred = Read-Host "enter-username e.g. domain\user.name"
$computers = Get-Content C:\Scripts\allcomputers.txt #| Where-Object { $_ }
#foreach ($computer in $computers) {
# Invoke-Command -computername $computer -scriptblock {msg * "INSERT MESSAGE TO STAFF HERE"} -Credential $cred
}
# Import-Module Citrix.XenDesktop.Admin?
# Add-PSSnapin Citrix?
$s = New-PSSession -cn DDC -Credential DOMAIN\Cred
Invoke-Command -Session $s -ScriptBlock { $sessions = Get-BrokerSession -UserName DOMAIN\User ;
Send-BrokerSessionMessage $sessions -MessageStyle Information -Title TestTitle -Text TestMessage
}
Get-PSSession | Remove-PSSession
If i use the command in the script block in an interactive session, the modules don't appear to be installed, hence the commented out 2 lines... :S
Thanks for the help - Working Code that will send out a message to all Citrix XDT sessions via PowerShell:
$s = New-PSSession -cn CitrixDDC -Credential Domain\Administrator
Invoke-Command -Session $s -ScriptBlock { import-module
Citrix.XenDesktop.Admin; Add-PSSnapin Citrix.*;
$sessions = Get-BrokerSession -UserName Domain\* `
Send-BrokerSessionMessage $sessions -MessageStyle Information -Title
TestTitle -Text TestMessage
}
Get-PSSession | Remove-PSSession

adding printer in remote machine is not working: invalid printer name

I have gone through many blogs for finding solution for this issue, but never find a solution.
$CompName = "test.domain.com"
$Printer = "\\122.21.10.11\PRINTER-NAME-1"
Invoke-Command -ComputerName $CompName -Scriptblock {
Param($p)
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($p)
} -ArgumentList $Printer
I have even tried PSRemoting and tried to execute the ps1 file from remote machine. the same script is working in local and not working remote.
Enter-PSSession -ComputerName "testserver.testdomain.com" -Authentication Credssp -Credential Get-Credential
Error:
Exception calling "AddWindowsPrinterConnection" with "1" argument(s): "The printer name is invalid. (Exception from HRESULT: 0x80070709)"
Updates:
Working without CredSSP:
Invoke-Command -ComputerName remotemac.mydomain.com -ScriptBlock {
Get-ChildItem C:\Users\myusername\Desktop
}
Working with CredSSP:
Invoke-Command -ComputerName remotemac.mydomain.com -ScriptBlock {
Get-ChildItem \\sharedmac\sharef
} -Authentication Credssp -Credential mydomain\myusername
Script is working, but not showing network printers:
Invoke-Command -ComputerName remotemac.mydomain.com -ScriptBlock {
(New-Object -ComObject WScript.Network).EnumPrinterConnections()
} -Authentication Credssp -Credential mydomain\myusername
Script gives error: Invalid Printer name
$Printer = "\\172.26.30.13\SDB1-FLOOR1-B2" # I have tried this input in single, double, with and without escape character
Invoke-Command -ComputerName remotemac.mydomain.com -ScriptBlock {
Param($p)
(New-Object -Com WScript.Network).AddWindowsPrinterConnection("$p")
} -ArgumentList $Printer -Authentication Credssp -Credential mydomain\myusername
I'm totally stuck.
I heard we can use Group Policy, is there anyway we can automate this using group policy?

Invoking remote powershell command not returning all results

I'm pretty new to powershell and I'm trying to invoke a remote powershell command to return the size of a drive but am having trouble.
If I run the below command directly on the server, then I get a result of 4.
import-module virtualmachinemanager
$checks = get-vm -Name DC1 | get-scvmcheckpoint
foreach ($disk in $checks){
$disk.virtualdiskdrives.virtualharddisks.size
}
I then try to run the command remotely using the below, but I don't get a result. The $checks variable contains a number of other values though.
$session = New-PSSession -ComputerName VM01 -ConfigurationName Microsoft.Powershell32 -Credential administrator
$checks = Invoke-Command -Session $session -ArgumentList VM01 -ScriptBlock {
import-module virtualmachinemanager
get-vm -Name DC1 | get-scvmcheckpoint
}
foreach ($disk in $checks){
$disk.virtualdiskdrives.virtualharddisks.size
}
The most likely issue here, (haven't tested the code on actual VMM server) is that objects returned from remote session are Serialized and De-serialized. Here is a reference How objects are sent to and from remote sessions.
To get around this, I would suggest doing all the processing on a remote machine and only return simple PS objects.
$session = New-PSSession -ComputerName VM01 -ConfigurationName Microsoft.Powershell32 -Credential administrator
$checks = Invoke-Command -Session $session -ArgumentList VM01 -ScriptBlock {
import-module virtualmachinemanager
$disks = get-vm -Name DC1 | get-scvmcheckpoint
foreach ($disk in $disks){
$disk.virtualdiskdrives.virtualharddisks.size
}
}
foreach ($disk in $checks){
write-host "Disk size = $disk"
}

nested scriptblocks in a powershell remote session

I am trying to run a script block on a remote machine, but i don't to be prompted for credentials, i want to pass them in the script.
Some commands may but the commands i want to run are access denied unless i provide the credential.
for example this command can work:
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {ls }
but this wont work unless -credential is passed (Invoke-Command on target)
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {Invoke-Command -computername $Env:COMPUTERNAME -Credential $Cred -ScriptBlock {ls} }
the same way what i want to achieve causes access denied problem (starting a process)
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {[System.Diagnostics.Process]::Start("C:\Myprocess.exe", $localArgs, "UserName", $credential.Password, "MyDomain")}
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $setError -Scriptblock {$Domain = "domain";$PassSec = ConvertTo-SecureString $( "password") -AsPlainText -Force ; $Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $($domain + "\" + "userName"),$passSec; Invoke-Command -computername $Env:COMPUTERNAME -Credential $Cred -ScriptBlock {C:\Myprocess.exe } }