Adding Current User To Administrators Group - powershell

I'm working on a script that will check if a user is an Administrator and then if they're not it'll add them on the spot, logoff, and then I can log back on to test. This is the part I'm running into problems:
$Cred = Get-Credential ("$env:COMPUTERNAME\Administrator")
$Group = [ADSI]("WinNT://"+$env:COMPUTERNAME+"/Administrators,Group")
$User = $env:USERNAME
$Domain = $env:USERDOMAIN
Invoke-Command -Computername localhost -Cred $Cred -ScriptBlock {$Group.add("WinNT://$Domain/$User,user")}
Everytime I run this I get the following error:
You cannot call a method on a null-valued expression.
Any ideas what I can do to fix this issue?
Working solution:
$Cred = Get-Credential ("$env:COMPUTERNAME\Administrator")
$User = $env:USERNAME
$Domain = $env:USERDOMAIN
Invoke-Command -Computername localhost -Cred $Cred -ScriptBlock {
param ($User, $Domain, $ComputerName)
$Group = [ADSI]("WinNT://$ComputerName/Administrators,Group")
$Group.add("WinNT://$Domain/$User,user")
} -ArgumentList $User, $Domain, $ENV:COMPUTERNAME

Invoke-Command will know nothing about $Group variable, that's reason why it does not work like that. You need to pass your variables to scriptblock using -ArgumentList parameter.
Also: I would rather define things like $Group inside this scriptblock:
$Cred = Get-Credential ("$env:COMPUTERNAME\Administrator")
$User = $env:USERNAME
$Domain = $env:USERDOMAIN
Invoke-Command -Computername localhost -Cred $Cred -ScriptBlock {
param ($User, $Domain, $ComputerName)
$Group = [ADSI]("WinNT://$ComputerName/Administrators,Group")
$Group.add("WinNT://$Domain/$User,user")
} -ArgumentList $User, $Domain, $ENV:COMPUTERNAME
HTH
Bartek
PS: just one question: why not doing it simple way, with:
net localgroup administrators domain\user /add

Related

Need to execute winrm set winrm/config/client '#{TrustedHosts="192.168.4.231"}' command from PowerShell script from remote

I am firing following script from remote machine to add the executer IP (192.168.4.231) in trusted list. but the below script is getting fired but not I am not getting desired results.
Please let me know is there any wrong way I am executing below script.
$servers = #("192.168.4.236")
foreach($server in $servers) {
$username = 'administrator'
$password = '*******'
$pw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
$s = New-PSSession -ComputerName $server -Credential $cred
Enter-PSSession $s
Invoke-Command -Session $s -Scriptblock {
Invoke-Expression 'winrm set winrm/config/client '#{TrustedHosts="192.168.4.231"}''
}
Write-Host "Completed"
Remove-PSSession $s
}

Enter PSSession with Variable for ComputerName

I am trying to enter a PSSession using -Computername $Server which was previously defined, but I can't seem to get this to work.
I have tried single, double, and no quotes around the variable at all. What am I doing wrong?
$Servers = Import-Csv "C:\Users\username\Desktop\DNS.csv"
$secpass = ConvertTo-SecureString 'mypassword' -AsPlainText -Force
$myCred = New-Object System.Management.Automation.PSCredential("username", $secpass)
foreach ($Object in $Servers) {
$Server = $Object.Name
Enter-PSSession -ComputerName "$Server" -Credential $myCred
sl HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters
Invoke-Command -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters}
Exit-PSSession
}
We use enter pssession for creating an interactive session with the remote computer.
In your case, you do not need to have an interaction with the remote system. You just need to fetch the details from the remote systems which are present in the csv file.
So, Instead of this:
foreach($Object in $Servers) {
$Server = $Object.Name
Enter-PSSession -ComputerName "$Server" -Credential $myCred
sl HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters
Invoke-Command -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters}
Exit-PSSession
}
Do This:
foreach($Object in $Servers)
{
$Server = $Object.Name
Invoke-Command -ComputerName $Server -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters} -Credential $myCred
}
Note: I believe you have enabled PSRemoting and have edited trusted hosts.
The ComputerName param of Invoke-Command will accept an array of servers so you can do away with the foreach loop entirely and simplify your code to:
$Servers = Import-Csv "C:\Users\username\Desktop\DNS.csv" | Select-Object -ExpandProperty Name
$secpass = ConvertTo-SecureString 'mypassword' -AsPlainText -Force
$myCred = New-Object System.Management.Automation.PSCredential("username", $secpass)
Invoke-Command -ComputerName $Servers -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters} -Credential $myCred

Execute remote PS command properly

I'm trying to change passwords on more than 1000 hosts running windows server 2008/2012. They assigned to different domains, so I connect to them via their IP, all of them have PowerShell remoting open.
Stuck at my script implementation. For now I just want to connect to single host and change the password of the user or admin whatever.
Here is the code I use
$username = "UserWhose Password I want to change"
$password = ConvertTo-SecureString "users old password" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$serverNameOrIp = "host ip address here"
$s = New-PSSession -ComputerName $serverNameOrIp -Authentication default -Credential $cred
#invoke the scriptblock remotely
$sb = {
"[ADSI]`$Admin=`"WinNT://$env:COMPUTERNAME/$env:USERNAME`""
"`$Admin.SetPassword(`"Users new password`")"
}
Invoke-Command -Session $s -ScriptBlock $sb
Remove-PSSession $s
Now, the console output I get:
PS C:\> ./script
[ADSI]$Admin="WinNT://WIN-TA49U0TR9GT/Administrator"
$Admin.SetPassword("Users new password")
PS C:\>
"WinNT://WIN-TA49U0TR9GT/Administrator" belongs to remote host, my local computername and a username are different.
I'm not getting any error or proper output here. The password isn't changing. If I try to run these commands manually on any host - it works.
Any suggestions? Maybe a working solutions?
You define the commands you want to run on the remote host as strings inside a scriptblock. When you invoke the scriptblock on the remote host it does what PowerShell does with all bare strings: echo them.
Remove the outer quoting and escaping and the code should work as you expect:
$sb = {
[ADSI]$Admin = "WinNT://$env:COMPUTERNAME/$env:USERNAME"
$Admin.SetPassword("Users new password")
}
The scriptblock already prevents variables from being expanded in the current context.
Posting complete working script, that accept console arguments, connect to specified host and change the user password.
ARGS = IP USERNAME OLDPASS NEWPASS
Hope this will help somebody
$serverNameOrIp = $args[0]
$username = $args[1]
$password = ConvertTo-SecureString -String $args[2] -AsPlainText -Force
$newPassword = $args[3]
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$s = New-PSSession -ComputerName $serverNameOrIp -Authentication default -Credential $cred
$sb = {
param($newPassword)
[ADSI]$Admin = "WinNT://$env:COMPUTERNAME/$env:USERNAME"
$Admin.SetPassword($newPassword)
}
Invoke-Command -Session $s -ScriptBlock $sb -args $newPassword
Remove-PSSession $s

Acess exe from unc path

i wan to run portqry from different forest using below script but i receive path can't be found error. while accessing the file from network share i can access it manually with no issue from remote domain
# Get forest name
$domain = "spos02600287.test.net"
$contextType = [system.directoryservices.activedirectory.Directorycontexttype]::Domain
$domain ="$domain"
$domainContext = new-object system.directoryservices.ActiveDirectory.DirectoryContext #($contextType,$domain)
#Query the Forest and PDC Role Emulator
$Server = [system.DirectoryServices.Activedirectory.Domain]::GetDomain($domaincontext)
$passwords = "newtemp123"
$user = "$domain\Administrator"
$password = $Passwords | ConvertTo-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -argument $user, $password
$PDC =$server.Name
foreach ( $serv in $PDC){
$Server = "d.root-servers.net"
$Port = "53"
Invoke-Command -ComputerName $serv -Credential $creds -ScriptBlock {\\10.28.64.15\EXE\portqry.exe -n $Server -e $Port -p UDP }}
What you are experiencing looks like the famous PowerShell double hop issues.
Basically, when remoting via Invoke-command you can't access a remote location.
Also, You seem to be missing brackets after "-scriptBlock"?
Here is some more information on the issue.
And here, from MSDN.
The issue was resolved by just adding -authentication credssp in the invoke command line like below
Invoke-Command -ComputerName $serv -Credential $creds -authentication credssp -ScriptBlock {...}

How do I pass a powershell argument to a non powershell command?

I runing the following simple powershell command on a remote server. However I need to pass a variable to the NET LOCALGROUP command:
$serverName = "SCO32"
$groupName = "SCO33_Local_Admins"
$Session = New-PSSession -ComputerName $serverName
Invoke-Command -Session $Session -ScriptBlock {
$args[1]
$args[0]
net localgroup administrators domainname\$args[1] /ADD
} -ArgumentList $serverName, $groupName
The arguments are passing correctly as is the remote connection, it just doesn't seem to be able to execute the command because it's trying to use the $args[1] as a literal and not domainname\SCO33_Local_Admins
Thanks in advance.
$servername = 'sv1'
In v2:
Invoke-Command -Session $Session -ScriptBlock {
param($servername, $group)
net localgroup administrators domainname\$servername /ADD
} -ArgumentList $serverName, $groupName
Or in v3
Invoke-Command -Session $Session -ScriptBlock {
net localgroup administrators domainname\${using:servername} /ADD
}
Or:
Invoke-Command -Session $Session -ScriptBlock {
net localgroup administrators domainname\$($args[1]) /ADD
} -ArgumentList $serverName, $groupName
Just like in a function or in a script you can assign parameters to a scriptblock. While using the automatic $args may not work for you, you can do this:
$serverName = "SCO32"
$groupName = "SCO33_Local_Admins"
$Session = New-PSSession -ComputerName $serverName
Invoke-Command -Session $Session -ScriptBlock {
Param($SrvName,$GrpName)
net localgroup administrators domainname\$GrpName /ADD
} -ArgumentList $serverName, $groupName