I'm tring to run Powercli script from VM that have all the modules nedded.
The script should insert other VM to domain.
$ScriptText ="Add-Computer -DomainName foofoo.com -DomainCredential " + $DomainC +" -OUPath 'OU=CACI,OU=Computers,OU=bla,OU=Regions,DC=bla,DC=com'"
echo $Script
Invoke-VMScript -vm $VMName -GuestCredential $AdminC -ScriptText $ScriptText
all the variables inserted correctly.
runing
Add-Computer -DomainName foofoo.com -DomainCredential $DomainC -OUPath 'OU=CACI,OU=Computers,OU=bla,OU=Regions,DC=bla,DC=com'
from the other vm poweshell console is running well and the output message WARNING: The changes will take effect after you restart the computer ..
$Script return:
Add-Computer -DomainName foofoo.com -DomainCredential System.Net.NetworkCredential -OUPath 'OU=CACI,OU=Computers,OU=bla,OU=Regions,DC=bla,DC=com'
but after that this script stuck and I have no error or other output.
Any idea what is the reason for that ?
The Add-Computer CMDlet takes a credential object for the domain credential parameter. By trying to convert that to a string in your $scripttext variable - you're losing the credential type in the conversion. You need to make a credential object inside your script text rather than passing in a variable containing the credential object. This adds some complexity because you generally want to pull a password from a secure vault. The below examples shows how to include the password as a plain text - but this isn't really advised for obvious reasons.
$scripttext = #'
$user = "UserName"
$password = ConvertTo-SecureString "bar" -AsPlainText -Force
$DomainC = New-Object PSCredential $user, $password
Add-Computer -DomainName foofoo.com -DomainCredential $DomainC -OUPath 'OU=CACI,OU=Computers,OU=bla,OU=Regions,DC=bla,DC=com'
'#
Invoke-VMScript -vm $VMName -GuestCredential $AdminC -ScriptText $ScriptText
Related
Using this Powershell script I try to write and read a variable on VM from host.
$Username = 'administrator'
$Password = 'password'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
#Added value to a variable on VM
Invoke-Command -VMName VM_Windows_2016 -Credential $Cred -ScriptBlock {$InstallPath="C:\Install\install-1.ps1"}
#Trying to read the variable on VM but with no result
Invoke-Command -VMName VM_Windows_2016 -Credential $Cred -ScriptBlock {Write-Host($InstallPath)}
As you see the result is empty. Can anyone help me to show how to write and read an variable on VM from host machine? Thanks!
When using Invoke-Command to run a command remotely, any variables in the command are evaluated on the remote computer. So when you run the first Invoke-Command you are only defining the variable $InstallPath and terminating the remote PS session. When you are run the Invoke-Command second time it create entirely new PS session, hence InstallPath would be null. Instead of this you can define and read the variable in a single Cmdlet like this.
$remoteScriptblock = {
$InstallPath = "C:\Install\install-1.ps1"
Write-Host($InstallPath)
}
Invoke-Command -VMName VM_Windows_2016 -Credential $Cred -ScriptBlock $remoteScriptblock
If you still want to run this in multiple Cmdlets you may consider Run a command in a persistent connection
Good evening,
I'm trying to write a Powershell script that will connect to a remote server via SCP and upload or download files/folders. Ultimately this is the script that I would like Jenkins to run.
So far I'm using Posh-SSH and having good success. The only issue is, no matter what I have tried so far, it will always prompt me for my credentials. This, obviously, makes it not entirely automatic.
I have attached a few things I've tried. Hopefully someone can help me out with this!
The basic command I'm testing with:
get-scpfolder -computername '111.111.111.111' -credential $credential
-remotefile "/var/myFolder" -localfile 'C:\Users\Me\destFolder'
Again, this works, but it requires me to enter my credentials.
I saw this command online:
$Password = "pass"
$User = "admin"
$ComputerName = "111.111.111.111"
$Command = "get-scpfolder -computername $ComputerName -credential $Credentials -localfolder 'C:\Users\Me' -remotefolder '/var/destFolder"
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
$SessionID = New-SSHSession -ComputerName $ComputerName -Credential $Credentials #Connect Over SSH
Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command # Invoke Command Over SSH
However this returns ExitStatus 1 and nothing happens. I have tried a few variations of the $Command including the credentials or not, for example, and I can't get any of it to work.
I have a centralized server from which i can run the following PowerShell command to get the clustergroup of cluster servers.
Enter-pssession -computername (ip-address) -credential (domain user)
And it prompts me to enter password then i get the session and execute
get-clustergroup
Okay till this it is fine.
Now i wanted to make this fully automated by converting in to a PowerShell script
The following commands works well when i run it in Powershell ISE and gets me the output of get-clustergroup
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$user = "domain\user"
$cred = New-Object System.Management.Automation.PSCredential ($user,$password)
Enter-PSSession -ComputerName IP.Add.RE.SS -Credential $cred
get-clustergroup
but when i save the about script and run with PowerShell i get the following error.
get-clustergroup: the cluster service is not running
I want to automate the process by writing script to get get-clustergroup output of four cluster servers.
i am new to PowerShell scripting. how can i save the output?
Instead of creating a session to the other server, you can run the following which will run the command on the remote computer and return the output to your console:
Invoke-Command -ComputerName <IPAddress> -ScriptBlock { Get-ClusterGroup } -Credential $cred
You can store that output into a variable if you wish for future retrieval.
Since -ComputerName can accept an array object, you can modify your command to include all four of your servers. Below shows how to use all of your computer names and store the output in the variable $Output:
$Output = Invoke-Command -ComputerName "Server1","Server2","Server3","Server4" `
-ScriptBlock {Get-ClusterGroup} -Credential $cred
$Output
Your computer names could also be stored in a variable as an array. Then that variable can be used in your -ComputerName parameter:
$Computers = "Server1","Server2","Server3","Server4"
Invoke-Command -ComputerName $Computers -ScriptBlock { Get-ClusterGroup } -Credential $cred
See Invoke-Command for more information.
I am trying to join a vm to a domain. Here is the script:
Invoke-VMScript -vm $hostName -GuestUser $VMLocalUser -GuestPassword $VMLocalPWord -ScriptType Powershell "Add-Computer -ComputerName $hostName -LocalCredential $VMLocalCredential -DomainName $domainName -Credential $VMLocalCredential -Restart -Force"
While executing the script freezes at 0% completion. Please let me know if am doing something wrong.
Running that add-computer command on the machine, I had trouble getting the ComputerName command to recognise which lead me to this
Issue Adding PC to domain and changing name at the same time
Alternatively use netdom.
Invoke-VMScript -VM $vmname -GuestUser $VMLocalUser -GuestPassword $VMLocalPWord -ScriptType Powershell "netdom join /d:mywork.domain computername /userd:domainaccount /passwordd:pwd"
I have spent the last 4 hours on this issue and would greatly appreciate any input you might have.
I need to call a powershell script with different credentials and pass arguments onto that script.
Following the installation of a program wrapped in WISEScript this script kicks off to gather AD accounts for the machine and remove them from specific AD Security Groups. Unfortunately as the script runs locally I cannot use ActiveDirectory modules in powershell as not all machines in our environment have RSAT.
The initial script is run from an elevated account on the machine:
$creds = New-Object System.Management.Automation.PsCredential("DOMAIN\USER", (ConvertTo-SecureString "Password" -AsPlainText -Force))
$ProfileGUIDS = Get-ChildItem 'hklm:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid'
$Groups = [ADSI]"LDAP://CN=Group4d_test,OU=GroupMigrationTesting,OU=TestOU,OU=US,DC=DOMAIN",[ADSI]"LDAP://CN=Group3d_test,OU=GroupMigrationTesting,OU=TestOU,OU=US,DC=DOMAIN"
Function Get-DistinguishedName ($strUserName)
{
$searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]'')
$searcher.Filter = "(&(objectClass=User)(samAccountName=$strUserName))"
$result = $searcher.FindOne()
if ($result)
{
Return $result.GetDirectoryEntry().DistinguishedName
}
}
forEach ($GUIDkey in $ProfileGUIDS)
{
$GUID = Out-String -InputObject $GUIDKey
$index = $GUID.IndexOf("S-1")
$GUID = $GUID.Substring($index)
$GUID = $GUID.Substring(0,128)
$index = $GUID.IndexOf(" ")
$GUID = $GUID.Substring(0,$index)
$Profile = "hklm:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$GUID"
$ProfileItems = Get-ItemProperty $Profile
$SAM = $ProfileItems.ProfileImagePath
$index = $SAM.LastIndexOf("\")
$index ++
$SAM = $SAM.substring($index)
$UserDN = Get-DistinguishedName $SAM
$User = [ADSI]"LDAP://$UserDN"
if($User -ne $null)
{
forEach($group in $groups)
{
Right here is where I need to call the 2nd script with different credentials.
This is RemoveUsers.ps1, the script I need to run with different credentials:
param
(
[string]$group = "MyDefaultSAM",
[string]$user = "MyDefaultUser"
)
$Group.remove($User.ADsPath)
I have tried:
start-process powershell.exe -Credential $creds -NoNewWindow -ArgumentList "Start-Process $PSSCriptRoot\RemoveUsers.ps1 -Verb
This will run the script however I cannot specify any arguments
powershell.exe -file "$PSScriptRoot\RemoveUsers.ps1" -user $user -group $group
This calls the script with arguments but does not allow for the -Credentials switch
I have also tried:
$job = Start-Job -ScriptBlock {
powershell.exe -file "$PSScriptRoot\RemoveUsers.ps1" -user $user -group $group
} -Credential $creds
This runs but does not appear to work properly as the users remain in the AD groups.
Any help is appreciated.
Thanks - Jeff
**** UPDATE ****
Thanks for the information. When I add the changes you suggest I receive an error
Invoke-Command : Parameter set cannot be resolved using the specified named parameters
It appears, as I have found online, the -Credential switch cannot be used without the -Computer switch. If I specify $env:COMPUTERNAME or localhost for the computer I receive the error
\RemoveUsers.ps1 is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again
I can avoid this issue if I remove the -Credential switch and open the AD group to everyone. At this point I don't need to elevate a new powershell script and can add the command in the same. If I cannot resolve the issue with Invoke-Command this is likely what I will do.
**** UPDATE ****
What I ultimately had to do was use -Authentication Credssp in the argument list as there is an issue with using the AD Module via Invoke-Command. In addition I had to start the Win-RM service, Enable WSMacCredSSP (-role client on each machine and add a DelegateComputer entry and -role server on the server connecting to). Only after the service was started and an entry was made for WSManCredSSP was I able to use the Invoke-Command switch and have the AD Module work correctly.
This of course makes things more complicated and I decided just installing the AD Module on each PC (after finding a way to do it without RSAT) and forgetting about running the command remotely all together. Thanks for your help with the matter.
Thanks
You don't need to run PowerShell scripts with powershell.exe when calling them from another PowerShell script. Simply use the call operator (&). Also, I'd use Invoke-Command for running something inline with different credentials.
Beware that the scriptblock doesn't automatically know about the variables in the rest of your script. You need to pass them into the scriptblock via the -ArgumentList parameter. That is most likely the reason why removal didn't work when you ran RemoveUsers.ps1 as a job.
Something like this should work:
Invoke-Command -ScriptBlock {
& "$PSScriptRoot\RemoveUsers.ps1" -user $args[0] -group $args[1]
} -ArgumentList $user, $group -Credential $creds -Computer $env:COMPUTERNAME
This requires PSRemoting, though (run Enable-PSRemoting as an administrator).