register environment variables on remote computers in powershell - powershell

I am just trying to learn powershell and through some examples I found came up with the following script. I'm attempting to register some environment variables on the different servers. When I run it I get the error -
Invoke-Command : A positional parameter cannot be found that accepts argument 'System.Object[]'.
At C:\Users\gswartz\Desktop\regvalue.ps1:3 char:16
+ Invoke-Command <<<< -ComputerName $server [Environment]::SetEnvironmentVariable("xxxx", "xxxx", "Machine")
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
Here's the script. Can someone tell me what I'm doing wrong?
function set_vars($server) {
Invoke-Command -ComputerName $server [Environment]::SetEnvironmentVariable("xxxx", "xxxx", "Machine")
Invoke-Command -ComputerName $server [Environment]::SetEnvironmentVariable("xxxx", "xxxx", "Machine")
Invoke-Command -ComputerName $server [Environment]::SetEnvironmentVariable("xxxx", "xxxx", "Machine")
Invoke-Command -ComputerName $server [Environment]::SetEnvironmentVariable("xxxx", "xxxx", "Machine")
Write-Host "vars set for $server"
}
$servers = #("server1","server2")
$servers | ForEach{
set_vars $_
}

Invoke-Command -ComputerName $Server -ScriptBlock { ... }

Related

PSSession search AD computers Powershell

Good afternoon everyone, I need to configure this script to run on AD machines, but I can only run it on the local machine, could you help me
I tried: $session = New-PSSession -ComputerName computer01
$events = Invoke-Command -ComputerName $session -ScriptBlock {`
param($days,$up,$down)
Get-EventLog `
-After (Get-Date).AddDays(-$days) `
-LogName System `
-Source EventLog `
| Where-Object {
$_.eventID -eq $up `
-OR `
$_.eventID -eq $down }
} -ArgumentList $NumberOfDays,$startUpID,$shutDownID -ErrorAction Stop
however it generated the error below:
Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of
strings.
At line:68 char:15
+ ... $events = Invoke-Command -ComputerName $session -ScriptBlock {`
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.String[]:String[]) [Invoke-Command], ArgumentException
+ FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

System Center Configuration Manager - PowerShell Remoting

I have a primary SCCM server - "ABC"
Later I installed SCCM console and PowerShell Module on one more machine - "XYZ"
I am running below script from server - "OPQ" and trying to remote "XYZ" (on which i installed SCCM Console Recently)
Script ::
$Session = New-PSSession -ComputerName "XYZ" -Authentication Kerberos -Credential $Cred -ConfigurationName Microsoft.PowerShell32
Invoke-Command -Session $Session -ScriptBlock {
Import-module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
Set-Location PS1:\
}
ERROR ::
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
+ CategoryInfo : OpenError: (PS1:PSDriveInfo) [Import-Module], UnauthorizedAccessException
+ FullyQualifiedErrorId : Drive,Microsoft.PowerShell.Commands.ImportModuleCommand
+ PSComputerName : XYZ
Cannot find drive. A drive with the name '' does not exist.
+ CategoryInfo : ObjectNotFound: (PS1:String) [Set-Location], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
+ PSComputerName : XYZ
Well it appears you have a permissions issue. Here is how I executed a remote command in my SCCM environment, via my PSS:
$device = Invoke-Command -Session $sess -ScriptBlock {
Import-Module (Join-Path (Split-Path $env:SMS_ADMIN_UI_PATH)
ConfigurationManager.psd1)
Push-Location -Path ((Get-WmiObject -Namespace "root\SMS" -Class
"SMS_ProviderLocation" | Select-Object -ExpandProperty SiteCode) + ":")
Get-CMDevice -Name $env:COMPUTERNAME
Pop-Location
}
$device
RunspaceId : cbc7e008-d92c-4ba3-94a3-b75f8005be98
SmsProviderObjectPath : SMS_CM_RES_COLL_SMS00001.ResourceID=16777221
AADDeviceID : 00000000-0000-0000-0000-000000000000
AADTenantID : 00000000-0000-0000-0000-000000000000
ActivationLockBypassState :
ActivationLockState :
ADLastLogonTime : 3/31/2020 11:23:38 PM
ADSiteName : XXXX-XX
...
Note that if you're not remoting to your PSS, you will need to specify your PSS in the Get-WmiObject command, e.g.:
(Get-WmiObject -ComputerName [YOUR PSS] -Namespace "root\SMS" -Class "SMS_ProviderLocation" | Select-Object -ExpandProperty SiteCode) + ":"
I was able to resolve this issue by saving the credentials on the XYZ server and then calling them under my INvoke-Command.
Like This :
$Session = New-PSSession -ComputerName "XYZ"
Invoke-Command -Session $Session -ScriptBlock {
$password = Get-Content -Path D:\Creds\creds.txt | ConvertTo-SecureString
$Cred = New-Object System.Management.Automation.PSCredential ("domain\UserId", $password)
Then the rest of the code. ... .. . . .
}

Powershell core to powershell

I'm running an Ubuntu EC2 instance with Pwsh installed to remote execute AD commands on one of our servers. 2sd hop is set-up correctly and i'm able to run AD commands but when executing my script i get the following error (Scripts works fine directly on the 2sd hop machine):
The search filter cannot be recognized
+ CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException + FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser
+ PSComputerName : corpmaint02
#!/usr/bin/pwsh
$employeeEmail = 'myemail#contoso.com'
$session = New-PSSession -ComputerName corpmaint02 -ConfigurationName corpmaint02 -Credential contoso\myadminaccount
Invoke-Command -Session $session -ArgumentList $employeeEmail -ScriptBlock{
Get-ADUser -Filter "EmailAddress -eq '$employeeEmail'" -Properties EmailAddress | Disable-ADAccount
Write-Host $employeeEmail has been 'disabled.'
}
Remove-PSSession -ID $session.ID
[GC]::Collect()
Any help would be appreciated.
Update: new code:
#!/usr/bin/pwsh
$cred=Get-Credential domain\myadmin
$employeeEmail = 'myemail#contoso.com'
Invoke-Command -ComputerName corpmaint02 -Credential $cred -ConfigurationName corpmaint02 -Authentication Negotiate -ArgumentList $employeeEmail -$
Get-ADUser -Filter "EmailAddress -eq '$($Args[0])'" -Properties EmailAddress | Disable-ADAccount -verbose
Write-Host $employeeEmail has been 'disabled.'
}
I modified my code as follow and it works expect for the lack of permissions to disable the account which odd because my admin account has rights to do so.
Insufficient access rights to perform the operation
+ CategoryInfo : NotSpecified: (CN=xxxxx\domain,DC=com:ADUser) [Disable-ADAccount], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8344,Microsoft.ActiveDirectory.Management.Commands.DisableADAccount
+ PSComputerName : corpmaint02
New code to elevate:
#!/usr/bin/pwsh
$cred=Get-Credential domain\myadmin
$employeeEmail = 'user1#contoso.com'
Invoke-Command -ComputerName corpmaint02 -Credential $cred -ConfigurationName corpmaint02 -Authentication Negotiate -ArgumentList $employeeEmail,$cred -ScriptBlock{
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$testadmin = $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
if ($testadmin -eq $false) {
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
exit $LASTEXITCODE
}
Get-ADUser -Filter "EmailAddress -eq '$($Args[0])'" -Properties EmailAddress | Disable-ADAccount -verbose -Credential $Args[1]
}
Write-Host $employeeEmail 'has been disabled.'
Invoke-Command isn't running with elevated rights, so you can retrieve data but not make changes.
https://ss64.com/ps/syntax-elevate.html
If you use Invoke-Command to run a script or command on a remote computer, then it will not run elevated even if the local session is. This is because any prompt for elevation will happen on the remote machine in a non-interactive session and so will fail.
You can try self elevating in the Invoke-Command scriptblock (from the link above)
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
# Relaunch as an elevated process:
Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path) -Verb RunAs
exit
}
# Now running elevated so launch the script:
& "d:\long path name\script name.ps1" "Long Argument 1" "Long Argument 2"

Problem with enter-pssession: "A positional parameter cannot be found that accepts argument"

I'm trying to set up PS Remoting/Win-RM and have the following:
$primary = 'server1'
$user = $env:UserName
$admUser = Get-Credential -UserName "domain\adm-$user" -Message 'Enter your *ADMIN* password:'
Enter-PSSession -ComputerName $primary -Credential $admUser {
hostname
}
However, this is returning the following error (I've tested this from a console and it works, so there's something wrong with my script):
Windows PowerShell credential request.
Enter your *ADMIN* password:
Password for user domain\adm-user1: ***************
Enter-PSSession : A positional parameter cannot be found that accepts argument '
hostname
'.
At line:5 char:1
+ Enter-PSSession -ComputerName $primary -Credential $admUser {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Enter-PSSession], ParameterBindingException
+ FullyQualifiedErrorId :PositionalParameterNotFound,Microsoft.PowerShell.Commands.EnterPSSessionCommand
What am I doing wrong? Thanks in advance!
Enter-PSSession opens a console connection to a remote system.
If you want to run a command on a remote system, you'd want to use Invoke-Command.
Also, you 100% always need to pass scriptblocks into some parameter (minus some edge cases where it's accepted by default). In this case, we need to use -Scriptblock.
Example:
Invoke-Command -ComputerName $primary -Credential $admUser -ScriptBlock {
hostname
}
or
$session = New-PSSession -ComputerName $primary -Credential $admUser
Invoke-Command -Session $session -ScriptBlock {hostname}
Invoke-Command -Session $session -ScriptBlock {$env:USERNAME}
Disconnect-PSSession -Session $session

PowerShell Issue regarding entering a PS Session and setting permissions

I am currently making a script to create a folder which then creates an AD group and links them together. I then connect to our server in the data centre to set the permissions.
To do this I need to enter a PSSession and find the folder and set the permissions. Unfortunately, it's not working. Any help would be appreciated.
Script
#Get ADM Credentials
$Cred = Get-Credential
# PowerShell's New-Item creates a folder
$Name = Read-Host "What is the name of the folder?"
$Location = Read-Host "What is the folder path? i.e B:\Collaboration\"
New-Item -Path $Location -Name $Name -ItemType "directory"
#Invoke-Item $Location
# Powershell creates an AD group
$Groupname = Read-Host "What is the group name? i.e. SS COLLABORATION BEN"
New-ADGroup -path "OU=StorSimple Centralisation Groups,OU=Groups,OU=Northgate PLC,DC=northgatevehiclehire,DC=net" -Name $Groupname -GroupCategory Security -GroupScope Global -DisplayName $Groupname -Description "Access to $Location" -Credential $cred
#Connect to StudFS01
$Folderpath = Read-Host "What is the path of the folder in StudFS e drive? i.e. Vehicle Sales\TOM Information"
Enter-PSSession -ComputerName Studfs01 -Credential $Cred
Start-Sleep -Seconds 10
Set-Location -Path E:\CentralisedData\Data\$folderpath
#Set Permissions
$rule=new-object System.Security.AccessControl.FileSystemAccessRule ("northgatevehiclehire.net\Domain Admins","FullControl","Allow")
$rule2=new-object System.Security.AccessControl.FileSystemAccessRule ("northgatevehiclehire.net\StorSimple Centralisation Administrators","FullControl","Allow")
$rule3=new-object System.Security.AccessControl.FileSystemAccessRule ("$Groupname","Modify","Allow")
$acl = Get-ACL E:\CentralisedData\Data\$folderpath
$acl.SetAccessRule($rule,$rule2,$rule3)
Set-ACL -Path E:\CentralisedData\Data\$folderpath -AclObject $acl
Error Im getting is below
Set-Location : Cannot find drive. A drive with the name 'E' does not exist.
At C:\Users\ben.curtis-haigh\Documents\New Security Group Script.ps1:19 char:1
+ Set-Location -Path E:\CentralisedData\Data\$folderpath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (E:String) [Set-Location], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
Get-ACL : Cannot find drive. A drive with the name 'E' does not exist.
At C:\Users\ben.curtis-haigh\Documents\New Security Group Script.ps1:25 char:8
+ $acl = Get-ACL E:\CentralisedData\Data\$folderpath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (E:String) [Get-Acl], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetAclCommand
You cannot call a method on a null-valued expression.
At C:\Users\ben.curtis-haigh\Documents\New Security Group Script.ps1:26 char:1
+ $acl.SetAccessRule($rule,$rule2,$rule3)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
At C:\Users\ben.curtis-haigh\Documents\New Security Group Script.ps1:27 char:62
+ Set-ACL -Path E:\CentralisedData\Data\$folderpath -AclObject $acl
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand`
Thanks
Instead of Enter-PSSession which is meant for interactive use, you need to establish a new PSSession and then use Invoke-Command against it. Something like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ScriptBlock {
<CODE TO EXECUTE ON REMOTE SYSTEM HERE>
}
If you need to pass parameters/variables, you have two choices. The easiest (in newer versions of PowerShell) is the using statement like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ScriptBlock {
Set-Location -Path E:\CentralisedData\Data\$using:Folderpath
}
Another option is to pass your arguments with -ArgumentList and use Param() in the script block like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ArgumentList $Folderpath -ScriptBlock {
Param($Folderpath)
Set-Location -Path E:\CentralisedData\Data\$Folderpath
}
Instead of Enter-PSSession which is meant for interactive use, you need to establish a new PSSession and then use Invoke-Command against it. Something like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ScriptBlock {
<CODE TO EXECUTE ON REMOTE SYSTEM HERE>
}
If you need to pass parameters/variables, you have two choices. The easiest (in newer versions of PowerShell) is the using statement like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ScriptBlock {
Set-Location -Path E:\CentralisedData\Data\$using:Folderpath
}
Another option is to pass your arguments with -ArgumentList and use Param() in the script block like this:
$PSSession = New-PSSession -ComputerName Studfs01 -Credential $Cred
Invoke-Command -Session $PSSession -ArgumentList $Folderpath -ScriptBlock {
Param($Folderpath)
Set-Location -Path E:\CentralisedData\Data\$Folderpath
}