PowerShell invoke commands failing - powershell

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.

Related

PowerShell: Admin Rights - What is wrong?

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}

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
}

Cannot run PS1 with different credential

I have a script, which does multiple things on different servers. If I log on to a computer with my admin account, the script runs fine. However, I want to to be able to run it on my standard account by using my admin credential.
I have used invoke-command with -credential or get-credential at the beginning of my script but none has worked. I keep getting "access is denied"
Here is a part of my script.
$Computername = "Computer"
if (test-Connection -ComputerName $ComputerName -Count 1 -quiet) {Write-Host "`n$computername is ONLINE."}
else {Write-Host "`n$computername is OFFLINE."
Get-ADComputer -identity $computername
if (!$?) {Write-Host "`n$computername is not found in ActiveDir."}
Else {
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $dom.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root
$search.filter = "(&(objectclass=computer)(name=$computername))"
$search.findall() | %{$_.GetDirectoryEntry() } | %{$_.DeleteObject(0)}
Write-Host "`n$computername is deleted from ActiveDir."
}}

How to list all Computers Operating System while using different Credentials

i try to retrieve a list of Computer Names and their Current Operating System.
Everything works fine up to the point, where I have no Access with my Credentials on this certain server.
For explanation: For log into the servers i have to use another Account.
For every user ist CurrentUserName+"ad" (for ADministration)
The servers.txt is like
Server1
Server2
Server3
...
Let me show you 2 tries.
1.
$Login = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +"ad"
$cred = Get-Credential $Login
$servers = get-Content .\server.txt
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $servers -Credential $cred
$OS | Select-Object CSName, Caption, OSArchitecture | Export-CSV -path .\$(get-date -f yyyyMMd)_CurrentOS.csv
$OS | select CSName, Caption, OSArchitecture | Out-GridView -Title 'Current OS'
Everything is fine up to the point i add a Server where i have no logon rights.
After that i get the following error and NO server is succesfull.
Get-WmiObject : Zugriff verweigert (Ausnahme von HRESULT: 0x80070005 (E_ACCESSDENIED))
2.
$Login = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +"ad"
$cred = Get-Credential $Login
$servers = get-Content .\server.txt
foreach ($server in $servers)
{
Try {
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $server -Credential $cred -ea SilentlyContinue
} Catch {
Write-Host 'Logon Credentials not accepted. No access to'$Server'.' -fore white -back red
} Finally {
Write-Host 'Logon Credentials accepted. Grant access to'$Server'.'
}
}
$OS | Select-Object CSName, Caption, OSArchitecture | Export-CSV -path .\$(get-date -f yyyyMMd)_CurrentOS.csv
$OS | select CSName, Caption, OSArchitecture | Out-GridView -Title 'Current OS'
The output on the Screen is fine, except the "Out-GridView" Here is only the last Server shown in GridView.
Logon Credentials accepted. Grant access to DEBZIAPP104.
While adding this "bad server" i'll get
Logon Credentials accepted. Grant access to DEBZIAPP104.
Logon Credentials not accepted. No access to DEBZIAPP106.
Logon Credentials accepted. Grant access to DEBZIAPP106.
I want to list all servers that are fine. If there occurs a server where i have no logon rights, there should be shown a message and the script need to continue.
Please ask if anything is not clear.
Hope someone can help. :)
Greets,
Patrick
Try/Catch will only catch Terminating Errors.
This should set you straight:
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $server -Credential $cred -ea Stop

Running powershell script as multiple users

I have different accounts for my server admin and workstation admin roles. I want to run a powershell script that will query my ad to get a list of computers and the query each computer returned to check for a service. The first part needs to run as the server admin and the second as the workstation admin. Currently I use two separate scripts. Is it possible to integrate it into one script?
Here are my two scripts they both run on the one computer. The first script I run on my workstation but run as my server admin account as this is the only one with access to active directory. This script creates an XML file which is used by the second script. I run this script as my workstation admin account.
runas.exe /user:domain\srvadmin "powershell.exe -executionpolicy bypass -command c:\output\script1.ps1"
runas.exe /user:domain\wsadmin "powershell.exe -executionpolicy bypass -command c:\output\script2.ps1"
script1
import-module -name activedirectory -cmdlet get-adcomputer, get-adorganizationalunit;
$orgUnit = #("OU=Computers,DC=domain,DC=com")
$computerList = get-adcomputer -filter * -searchscope subtree -searchbase (get-adorganizationalunit $orgUnit).distinguishedname;
write $computerList | export-clixml c:\output\computerList.xml
script2
$computersInOU = import-clixml c:\output\computerList.xml
foreach ($comp in $computersInOU) {
if ($comp.Enabled) {
$cpu = get-wmiobject -class win32_processor -computername $comp.name
write "$comp.name $cpu"
}
}
You can cycle through an array of machines and use Invoke-Command to run scripts remotely:
$script = {Get-Process explorer}
$servers = #("Server1", "Server2") # or $servers = Get-ADComputer -filter blah1
$serverCred = Get-Credential "(Server)"
$workstations = #("WS1", "WS2") # or $workstations = Get-ADComputer -filter blah2
$workstationCred = Get-Credential "(Workstation)"
$servers | %{Invoke-Command $script -Computer $_ -Credential $serverCred}
$workstations | %{Invoke-Command $script -Computer $_ -Credential $workstationCred}
Update based on new question info:
You can combine your scripts like this:
$srvCred = Get-Credential "domain\srvadmin"
$wsCred = Get-Credential "domain\wsadmin"
Import-Module -name ActiveDirectory -cmdlet Get-ADComputer, Get-ADOrganizationalUnit;
$orgUnit = #("OU=Computers,DC=domain,DC=com")
$searchBase = (Get-ADOrganizationalUnit -Credential $srvCred $orgUnit).distinguishedname
$computersInOU = Get-ADComputer -Credential $srvCred -filter * -searchscope subtree -searchbase $searchBase;
foreach ($comp in $computersInOU) {
if ($comp.Enabled) {
$cpu = Get-WmiObject -Credential $wsCred -class win32_processor -computername $comp.name
write "$comp.name $cpu"
}
}