PowerShell: Admin Rights - What is wrong? - powershell

I am totally new with PowerShell and it might be a silly question
I have created a small script to add admin rights remotely:
$computername = Read-Host 'Computername';
$name = Read-Host 'UserName';
Enter-Pssession -computername $computername;
Add-LocalGroupMember -Group "Administrators" -Member $name;
If I try to run it all together it doesn't work
but if I try to run it separately, it works
$computername = Read-Host 'Computername'
Enter-Pssession -computername $computername;
then
$name = Read-Host 'UserName';
Add-LocalGroupMember -Group "Administrators" -Member $name;
Would you mind telling me what is wrong?
Thank you!

After you enter the PSSession in the script, the variable $name is set to $0 again, since you dont pass the variable through to the session.
I would try running the script like this:
$computername = Read-Host 'Computername'
$name = Read-Host 'UserName'
Invoke-Command {
param($name)
Add-LocalGroupMember -Group "Administrators" -Member $name
} -computer $computername -ArgumentList $name

This is basically the same as Paxz answer but as a one-liner.
you can use local variables in the script block of Invoke-Command by prepending "using:".
$computername = Read-Host 'Computername'
$name = Read-Host 'UserName'
Invoke-Command -ComputerName $computername -ScriptBlock {Add-LocalGroupMember -Group "Administrators" -Member $using:name}

Related

Can't create a remote admin using powershell [duplicate]

This question already has answers here:
How do I pass a local variable to a remote `Invoke-Command`? [duplicate]
(2 answers)
Closed 1 year ago.
Good afternoon.
I would like to ask for help.
I am trying to execute a script remotely.
When doing this, I get a NULL password error.
Please tell me how to be.
$pcName = #("pc1","pc2")
Invoke-Command -ComputerName $pcName {$UserPassword = ConvertTo-SecureString "test123456" -AsPlainText -Force}
Invoke-Command -ComputerName $pcName -ScriptBlock { New-LocalUser -Name "admintest" -Password $UserPassword -PasswordNeverExpires }
Invoke-Command -ComputerName $pcName -ScriptBlock { Add-LocalGroupMember -Group "Administrator" -Member "admintest" }
P.S I'm just learning.
Inside the scriptblock, variable $UserPassword is unknown. To be able to use the variable in the scriptblock, you need to either scope it with $using:UserPassword:
$UserPassword = ConvertTo-SecureString "test123456" -AsPlainText -Force
$pcName = "pc1", "pc2"
Invoke-Command -ComputerName $pcName -ScriptBlock {
try {
$newUser = New-LocalUser -Name "admintest" -Password $using:UserPassword -PasswordNeverExpires -ErrorAction Stop
Add-LocalGroupMember -Group "Administrators" -Member $newUser
}
catch {
Write-Warning "Could not create the new user:`r`n$($_.Exception.Message)"
}
}
OR
Have the scriptblock accept parameter(s) in a param(..) block and call like
$UserPassword = ConvertTo-SecureString "test123456" -AsPlainText -Force
$pcName = "pc1", "pc2"
Invoke-Command -ComputerName $pcName -ScriptBlock {
param ( [securestring] $Password )
try {
$newUser = New-LocalUser -Name "admintest" -Password $Password -PasswordNeverExpires -ErrorAction Stop
Add-LocalGroupMember -Group "Administrators" -Member $newUser
}
catch {
Write-Warning "Could not create the new user:`r`n$($_.Exception.Message)"
}
} -ArgumentList $UserPassword
P.S.
The group is called Administrators (plural)
I have used a try{..} catch{..} so you will receive an error message when things go wrong

Powershell Get-Acl for folders without access permissions

I wrote a script, which gives me all the permissions of a folder + subfolders for a user/group. However, the script only works, if my user has at least read permissions on all these folders. If he has no permissions, get-acl is denied.
Is there any way to work around this, as I don't want to manually switch my user everytime I execute this script.
Can I execute a powershell script with a different user? And if yes, how?
Thank you in advance, Colin
You have a few options that I can think of:
Option 1:
Create a helper file with the actual code you want to run and call it script.ps1 for instance:
[array]$users = "user1","user2","user3"
foreach($user in $users){
$creds = Get-Credential -UserName $user -Message "Enter the Users Password"
$Session = New-PSSession -Credential $creds
Invoke-Command -Session $Session -FilePath C:\Path\to\some\script.ps1
}
Option 2: Run a job for each user. After every task is finished, the new user credentials will be asked. Just add the code to the scriptblock
[array]$users = "user1","user2","user3"
foreach($user in $users){
$creds = Get-Credential -UserName $user -Message "Enter the Users Password"
$target = $user
$job = Start-Job -scriptblock {
param ($username)
Get-Acl C:\Users\$user #Bla bla the rest of your script
} -Args $user -credential $creds
do{
#Wait for the job to finish
}until($job.State -ne "Running")
Write-Host "Job finished with state $($job.State)"
}
Hope this helps!
Note that the creds object can also be automated, if you don't wish to type all the time. (Security principles not taken into account ;) )
$users = #()
$users += #{
username = "User1"
password = "Pass123!"
}
$users += #{
username = "User2"
password = "Pass123!"
}
foreach($user in $users){
$creds = New-Object System.Management.Automation.PSCredential($user.username,($user.password | ConvertTo-SecureString -AsPlainText -Force))
#Add the rest of the script from the chosen option
}

PowerShell Script Runs Locally, but Errors on Remote

I have a PowerShell script I am writing to create new users in our domain, as well as email address. The script works when I run it directly on Exchange. However, if I try to do it from my local PC either with Enter-PSSession or Invoke-Command I get the error:
The term 'Get-ADUser' is not recognized as the name of a cmdlet...
Running that same command from the local machine does work. And running that command on the remote machine works, just not if I run the script remotely.
Here is my script:
$cred = Get-Credential
$first_name = Read-Host -Prompt "What is the new user's first name?"
$last_name = Read-Host -Prompt "What is the new user's last name?"
$copy_from = Read-Host -Prompt "Copy from other user (leave blank if not)?"
$password = Read-Host -Prompt "New user's password?"
$ss_password = ConvertTo-SecureString -String $password -AsPlainText -Force
$new_user_name = $last_name.Substring(0,3) + $first_name.Substring(0,2)
$new_user_name = $new_user_name.ToLower()
Write-Host "Creating user $new_user_name..." -ForegroundColor Green
if ([string]::IsNullOrEmpty($copy_from))
{
Write-Host "Setting up new user (not copying...)" -ForegroundColor Yellow
New-ADUser -Name "$first_name $last_name" -AccountPassword $ss_password -SamAccountName $new_user_name -PassThru | Enable-ADAccount
}
else
{
$copy_from_user = Get-ADUser -Identity $copy_from
Write-Host "Copying user from: " $copy_from_user.Name -ForegroundColor Yellow
$ou = $copy_from_user.DistinguishedName -replace '^cn=.+?(?<!\\),'
New-ADUser -Name "$first_name $last_name" -AccountPassword $ss_password -Path $ou -SamAccountName $new_user_name -PassThru | Enable-ADAccount
$new_user = Get-ADUser -Identity $new_user_name
#Time to copy their group memberships
Get-ADUser -Identity $copy_from -Properties memberof | Select-Object -ExpandProperty memberof | Add-ADGroupMember -Members $new_user_name
}
$pn = $new_user_name + "#INDY"
Set-ADUser -Identity $new_user_name -GivenName $first_name -Surname $last_name -UserPrincipalName $pn
#Now create email
$email_select = Read-Host -Prompt "Select email domain (1. Woodmizer; 2. Lastec; 3. Brightstone)"
if ($email_select -eq 2)
{
$domain = "#lastec.com"
}
elseif ($email_select -eq 3)
{
$domain = "#brightstoneabrasives.com"
}
else
{
$domain = "#woodmizer.com"
}
$email_address1 = $first_name.Substring(0,1) + $last_name + $domain
Write-Host "Creating mailbox $email_address1..." -ForegroundColor Green
Enable-Mailbox -Identity $new_user_name -Database "Mailbox Database 1188513962"
Start-Sleep -s 10
Get-Mailbox -Identity $new_user_name | Set-Mailbox -EmailAddresses #{add="$email_address1"} -EMailAddressPolicyEnabled $false
Get-Mailbox -Identity $new_user_name | Set-Mailbox -PrimarySmtpAddress $email_address1 -EmailAddressPolicyEnabled $false
Write-Host "Finished." -ForegroundColor Green
If you want this script to run on machines that don't have the Active Directory module, you can simply add this to the top of your script to import the cmdlets via session..
$cred = Get-Credential "DOMAIN\adminuser"
$ADsession = New-PSSession -ComputerName DOMAINCONTROLLERNAME -Credential $cred
Import-Module -PSSession $ADsession ActiveDirectory
I also notice you're trying to run Exchange cmdlets..
$exchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://EXCHANGESERVER/PowerShell/" -Authentication Kerberos
Import-PSSession $exchSession
It looks like the ActiveDirectory module is not installed on that machine, you can install the MSFT RSAT tools to get it.
Try the following, It works!! {I tried after giving the Authentication type}
$pass = ConvertTo-SecureString -AsPlainText 'PASSWORD' -Force
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'USERNAME',$pass
$s=New-PSSession SERVERNAME -Credential $MySecureCreds -Authentication Credssp
Invoke-Command -Session $s -scriptblock {
Get-CsUser User
}

PowerShell invoke commands failing

This powershell is designed to add a user to either the Admin, Remote Desktop Users/User group depending on AD Group.
I tested on a Windows 7 Workstation and it worked great. When I try on a Windows 2012 Server it only adds the user to "Remote Desktop User" and not "Users" Advice please:
$user = $UserName
$group = "Domain Admins"
$members = Get-ADGroupMember -Identity $group -Recursive | Select - ExpandProperty SamAccountName
If ($members -contains $user) {
$AdminGroup = [ADSI]"WinNT://$TargetServer/Administrators,group"
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
$AdminGroup.Add($User.Path)
Start-Sleep -s 3
invoke-command -ComputerName $TargetServer {net localgroup administrators}
} Else {
$AdminGroup = [ADSI]"WinNT://$TargetServer/Remote Desktop Users,group"
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
$AdminGroup.Add($User.Path)
Start-Sleep -s 3
invoke-command -ComputerName $TargetServer {net localgroup Remote Desktop Users}
$AdminGroup = [ADSI]"WinNT://$TargetServer/Users,group"
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
$AdminGroup.Add($User.Path)
Start-Sleep -s 3
invoke-command -ComputerName $TargetServer {net localgroup Users}
}
Ok weird. If I reverse the "Remote Desktop User" and "User" code blocks, it works on both Server and Workstation. Weird but resolved. I would like to know why if anyone has an answer.

Adding Current User To Administrators Group

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