How to run commands on a remote computer using PSExec and PowerShell? - powershell

I am trying to install an .exe program remotely to many workstations in the domain.
The command I am trying to run in the remote computer's PowerShell instance:
.\PsExec.exe \\$Computer /s cmd /c %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File \\FileShare\Software\DellSupportAssist.ps1
And the script I am calling in the command above:
#Retrieves a list of computers in AD.
$Computers = Get-ADComputer -Filter 'Name -like "Workstation*"' | Select-Object -ExpandProperty Name
ForEach ($Computer in $Computers) {
#Opens a remote session into the computer.
.\PsExec.exe C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe \\$Computer
#Installs Dell SupportAssist for each computer
Invoke-WebRequest -Uri "https://downloads.dell.com/serviceability/catalog/SupportAssistInstaller.exe" -OutFile "C:\Users\$env:Username\Downloads\SupportAssistInstaller.exe"
Start-Process "C:\Users\$env:Username\Downloads\SupportAssistInstaller.exe" -ArgumentList "/q" -Wait -NoNewWindow
Write-Host "Installing Dell SupportAssist on $Computer" -ForegroundColor Green
#Checks whether Dell SupportAssist was successfully installed or not
if (Get-WmiObject -Class win32_product -ComputerName $Computer | Where {$_.Name -match "Dell Support*"} | Select-Object -ExpandProperty Name) {
Write-Host "Dell SupportAssist was successfully installed on $Computer" -ForegroundColor Yellow
} else {
Write-Host "Dell SupportAssist was not successfully installed on $Computer" -ForegroundColor Red
}
exit
}
I am having the following issues:
'Target name incorrect' (for half of the computers in the domain.)
.\PsExec.exe : The term '\FileShare\Software\DellSupportAssist.ps1' is not recognized as the name of a cmdlet, function, script file, or operable (for the computers I can connect to in the domain)

Related

Use PowerShell to install Windows Updates in vSphere

I have a cluster of vSphere windows clients approximately 100 that I want to remotely automate windows updates on weekly. I have listed all the windows machine out in text file on my desktop. I have run the PSWindowsUpdate module on my local windows10 machine with command:
Install-Module -Name PSWindowsUpdate and then executed the below script successful for my local machine to run windows updates.
#Import-Module PSWindowsUpdate
#Remove-Item -Path C:\Scripts\status.tx
#Start-Transcript -Path C:\Scripts\status.txt
#$Updates = "Critical Updates", "Security Updates"
#Get-WUInstall -AcceptALL- Verbose -IgnoreReboot -Category $Updates
#Write-Host "Done"
#Stop-Transcript
#Start-Sleep -s 120
#Restart-Computer -Force -Confirm:$false
-- after pc restarts run as PS As Administrator
#Get-WindowsUpdate
However, I am not a expert at PowerShell so, I do not know what to additionally script to accomplish the task of remotely updating 100 or so windows clients in vSphere.
Any suggestion would be appreciated.
You can try with the invoke-command. You can create a server list from a DC:
$Servers = Get-ADObject -Filter * -Properties Name,OperatingSystem | Where-Object OperatingSystem -like '*Server*'
And use this list with a loop like this
ForEach($_ in $Servers)
{
Invoke-Command -ScriptBlock {Get-WUInstall -AcceptALL- Verbose -IgnoreReboot -Category $Updates } -ComputerName $_.Name -ErrorAction SilentlyContinue
}

Invoke-Command doesn't return to local machine but software is installed

The tl;dr: I'm puzzled as to why my script isn't returning back to the deployment machine. Does anyone have an idea why?
I was provided an EXE and a couple arguments to install some software. I'm using PowerShell's Start-Process to run it. The deployment machine is Win Server 2012 domain controller, logged in and being run as domain admin. The test machines are two Windows 10 Pro domained machines. All three have PS 5.1.
Being a silent install, there is no user interaction required. If I run the exact command locally, via RDP, or in a pssession, with just c:\Software.exe /silent /arg2removed, it installs and returns as expected.
The script runs fine up to a point. Nothing happens after Start-Process inside Invoke-Command 's -ScriptBlock. In a separate PowerShell window, I can use Enter-PSSession for each of the two client machines, and Get-Service and Get-Process both show the software's service and background processes, respectively. I can Ctrl+c on the deployment machine and get back to a prompt. No errors are reported at any time.
Here's the Start-Process chunk. I've read the help and it doesn't sound like I'm missing anything that would allow the ScriptBlock to finish. If I prepend Start-Process with Write-Host (like we all do), it echoes the command that would run and I get back to a command prompt on the deployment machine.
# Start the installer.
Start-Process `
-FilePath "C:\${using:SrcExe}" `
-ArgumentList "/SILENT", "/arg2removed" `
-WorkingDirectory C:\ `
-Wait `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InstallErrors
Here's most of the script. The only items before Invoke-Command are where I set up $ComputersToInstallOn, enter the credentials (yes I'm sure they're correct), and supply the path to the EXE.
Invoke-Command `
-ComputerName $ComputersToInstallOn `
-Credential $Creds `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InvokeCommErrors `
-ScriptBlock {
# Get and print the destination machine's hostname
$ThisMachine = Get-Content Env:\COMPUTERNAME ; $ThisMachine
# Print the current date and time
Get-Date
# Check if Sentinel processes are running. If not, assume it's not installed.
$S1Procs = get-process sentinel*
if([string]::IsNullOrEmpty($S1Procs)) {
# Sentinel isn't installed. Continue.
# Map a drive letter to $SrcFolder. Not theoretically necessary but Start-Process complains when copying with the UNC path directly.
New-PSDrive `
-Name S `
-PSProvider FileSystem `
-Credential ${using:Creds} `
-Root ${using:SrcFolder} `
-verbose
# List remote folder
Get-ChildItem S:\
# Copy the $SrcExe to C:\
Copy-Item `
-Path "S:\${using:SrcExe}" `
-Destination C:\ `
-Verbose `
-ErrorAction Stop `
-ErrorVariable CopyErrors
# Unmount drive
Remove-PSDrive S -verbose
# Verify EXE exists locally
Get-ChildItem -Path C:\${using:SrcExe}
# If there were copy errors, abort.
if ($CopyErrors) {
Write-Host "There was an error copying '${using:SrcExe}' to $ThisMachine. Aborting."
exit 1 } else {
# All good so far. Continue to install.
Write-Host "$(Get-Date -UFormat '%Y%m%d %H:%M:%S') : Starting install on ${ThisMachine}. You may need to Ctrl+C to return to the local machine. Check processes on each machine though."
# Start the installer.
Start-Process `
-FilePath "C:\${using:SrcExe}" `
-ArgumentList "/SILENT", "/arg2removed" `
-WorkingDirectory C:\ `
-Wait `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InstallErrors
# ScriptBlock doesn't seem to make it to anything after Start-Process.
# Remove the EXE.
Remove-Item "C:\${using:SrcExe}" -Verbose -ErrorAction SilentlyContinue
exit 0
# Get-Process -Name Sentinel*
# echo "Sleeping. Now would be the time to abort."
# Start-Sleep 15
}
} else {
Write-Host "Sentinel appears to be installed and running."
$S1Procs
Get-Service -Name Sentinel* | Where-Object { $_.Status -match "Running" }
exit 0
}
}
if($InvokeCommErrors){
Write-Host "There were some errors."
}
EDIT: Added some requested info.

Issues running Script to install EXE on remote machines

I am trying to run a PowerShell script to install an exe remotely on a list of machines which I import as a CSV. I have copied the exe to the same location on all machines and I was orignally getting an executtion policy error which I have now resolved but now the exe fails to install.
Set-ExecutionPolicy -ExecutionPolicy Bypass -Force -Scope LocalMachine -WhatIf
$csv = Import-Csv "C:\test.csv"
foreach ($row in $csv) {
$Server = $row.server
Invoke-Command -ComputerName $server -ScriptBlock {
Start-Process -FilePath "C:\TEMP\Apps\ActiveX\ActXPack.EXE"
}
}

Flushdns and registerdns on multiple machine by powershell

Simple question but not able to find answer on google at the moment. My powershell version is 2. I want to flush and registerdns on multiple machines.
ipconfig /flushDns
ipconfig /registerdns
I can't use invoke command and psremoting is not enabled on machines.
Any advise how to flushdns & registerdns.
It's pretty easy with Invoke-wmimethod
Create a list of your computers in a file named servers.txt, then create a script like this :
$listofservers = Get-Content .\servers.txt
foreach ($servers in $listofservers) {
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ("cmd.exe /c ipconfig /flushdns") -ComputerName $servers
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ("cmd.exe /c ipconfig /registerdns") -ComputerName $servers
}
By default you'll not get the output of the command, but you'll only get information if the command sucessfully ran on remote computer through this value :
ReturnValue
If this value equal to 0 that means the command was sucessfully executed on the remote server.
If you want to get the command output, you can achieve it but adding output redirection to txt file :
$listofservers = Get-Content .\servers.txt
foreach ($servers in $listofservers) {
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ("cmd.exe /c ipconfig /flushdns > c:\flushdnsresult.txt") -ComputerName $servers
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ("cmd.exe /c ipconfig /registerdns > c:\registerdnsresult.txt") -ComputerName $servers
}
Then you'll find a txt file on your remote server containing the result output of cmd command.
If you upgrade your powershell version from 2 (highly recommended - I have a powershell & dotnet update script to do this also) you can use:
# Get Windows servers on Domain
####################
$serversraw=Get-ADComputer -Filter {(OperatingSystem -like "*windows*")}
# Filter responsive
####################
$serversup = $serversraw.name | where {Test-Connection $_ -quiet -count 1}
# Flush DNS & reregister
####################
Clear-DnsClientCache -cimsession $serversup
Register-DnsClientCache -cimsession $serversup

Configure Remote Desktop for Administrator with PowerShell

Is it possible to configure Remote Desktop for Administrator using PowerShell without installing the "Remote Desktop Session Host" role on all our servers? We're after the RemoteDesktopServices module.
The docs here: http://technet.microsoft.com/en-us/library/cc743159.aspx say
"To allow remote connections for administrative purposes only, you do not have to install an RD Session Host server."
but all the instructions for using PowerShell seem to require the extra role. Is it necessary, and if so, what the implications, as it seems to be a much broader set of functionality?
Using wmi you can do it without RDSH (copy&paste from here )
$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting `
-Namespace root\CIMV2\TerminalServices `
-Computer $Computer `
-Authentication 6 `
-ErrorAction Stop
$result = $RDP.SetAllowTsConnections(1,1)
if($result.ReturnValue -eq 0) {
Write-Host "$Computer : Enabled RDP Successfully"
"$Computer : RDP Enabled Successfully" | Out-File -FilePath $SuccessComps -Append
} else {
Write-Host "$Computer : Failed to enabled RDP"
"$Computer : Failed to enable RDP" | Out-File -FilePath $FailedComps -Append
}