PowerShell Script to Stop a service on multiple remote machines - powershell

I am trying to disable a service running on 250+ PCs. I would like to have a PowerShell script I can execute on a random PC in the network and let it disable a service on every PC I specify in an txt file. It's always the same service. The script should also ask for the credential of the PC that it is trying to connect to.
This is a Script to set DNS on every PC in computer.txt. It asks me for the "administrator" password for every PC.
function Set-DNSWINS {
#Get NICS via WMI
$remoteuser = get-credential $_\administrator
$NICs = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Credential $remoteuser -ComputerName $_ -Filter "IPEnabled=TRUE"
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Credential $remoteuser -ComputerName $_ -Filter "IPEnabled=TRUE"
foreach($NIC in $NICs) {
$DNSServers = "192.168.3.12","192.168.0.77"
$NIC.SetDNSServerSearchOrder($DNSServers)
$NIC.SetDynamicDNSRegistration("TRUE")
#$NIC.SetWINSServer("12.345.67.890", "12.345.67.891")
}
}
function Get-FileName {
$computer = Read-Host "Dateiname mit Computernamen"
return $computer
}
Get-Content computer.txt | ForEach-Object {Set-DNSWINS}

You can stop a service from the commandline using
net stop "servicename"
or in PowerShell
Stop-Service "serviceName"
There are probably better ways to automate this across multiple machines than your script.

Can use Set-Service to disable a service and Invoke-Command to run it remotely. Note you need to run Enable-PSRemoting on the remote computer and configure WSMAN to allow connecting to the remote PC:
function MyFunction{
$remoteuser = get-credential $_\administrator
$service = "MyService"
Invoke-Command -computer $_ -credential $remoteuser -scriptblock {
Stop-Service $service
Set-Service $service -startuptype Disabled
}
}
function Get-FileName {
$computer = Read-Host "Dateiname mit Computernamen"
return $computer
}
Get-Content computer.txt | ForEach-Object {MyFunction}

Related

Powershell and TPM how to manage bitlocker?

I am trying to script a powershell function manage-bde.exe (bitlocker) to add a key protector to systems without TPM. For some reason GPO is not working. I have not had any luck getting powershell to add the protector remotely. I can log on to the endpoint and use the built in wizard to encrypt and save the key to our repository but for some reason remote automated scripting eludes me. My question is really more of guidance. Can powershell only be used, to remotely manage systems with TPM? I have bitlocker enabled and encrypted on systems without but I have had to do it manually.
Start-Transcript -Path ".\bitlockertranscript.txt" -Force
foreach ($Computer in $List) {
if (test-Connection -ComputerName $Computer -Count 1 -Quiet ) {
Get-ADComputer -Identity $Computer -Property * | Select Name,OperatingSystem
Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm -computername $Computer | fl IsActivated_InitialValue, IsEnabled_InitialValue, IsOwned_InitialValue
$BitLocker = Get-WmiObject -ComputerName $Computer -Namespace Root\cimv2\Security\MicrosoftVolumeEncryption -Class Win32_EncryptableVolume
$id = $BitLocker.GetKeyProtectors(3).volumekeyprotectorid | Select -First 1
manage-bde.exe -cn $Computer -protectors -adbackup c:
manage-bde.exe -on C: -cn $Computer
Invoke-GPUpdate -Target $computer
} else
{"No Connection to $Computer"
}
}
Stop-Transcript

Formating List Problems in Powershell

I want to execute a few lines of code on every Server (160+).
For this I decided to get my Serverlist via Powercli and pass this list to Enter-PSSession.
...
Connect-VIServer -Server $VIServer -Credential $creds
$servers = Get-VM |select Name |where Name -Like "SV*"
...
foreach($server in $servers)
{
try{
Enter-PSSession -ComputerName $server -Credential $cred -ErrorAction Stop
Get-NetIPAddress |where AddressFamily -EQ 2 |where InterfaceAlias -Like "Ethernet" |select IPAddress
Exit-PSSession
}catch{
Write-Host "Error on $server"
}
}
the problem seems to be, that it takes an array as the ouput error is following
Error on #{Name=<$server>}
But I dont know how to handle this correctly
Use New-Pssession or Invoke-command for remoting. Enter-Pssession is interactive and the way you are doing it, the get-netipaddress is running on your local machine and not on your remote machine.
Use $servers.Name instead of $servers in your foreach loop.
foreach($server in $servers.Name) #This .name should fix your problem
{
try{
New-PSSession -ComputerName $server -Credential $cred -ErrorAction Stop -Name MySession
Invoke-Command -Session $MySession -ScriptBlock {Get-NetIPAddress |where AddressFamily -EQ 2 |where InterfaceAlias -Like "Ethernet" |select IPAddress}
Remove-PSSession
}catch{
Write-Host "Error on $server"
}
}

Unable to fetch IIS status from Remote server using Powershell

I am trying to fetch IIS status from remote server using powershell.
I have used command Get-Service but i don't recieve any output from this command.
Below is my code block.
$pass='pass'|ConvertTo-SecureString -AsPlainText -Force;
$Credentials = New-Object
System.Management.Automation.PsCredential("user",$pass);
$Service=invoke-command -computername "server" -credential $Credentials -
scriptblock {Get-Service|Where-Object Name -eq 'IISADMIN'}
if($Service.Status -eq 'Running')
{
write-host "IIS Running"
}
else
{
throw "IIS not running or Not installed"
}
I Checked your code and did not see any problem with it, Did you checked the service exists locally using Get-Service or Service Manager?
Anyway you don't have to use Invoke-Command for this, you can use the built in -ComputerName parameter of the Get-Service cmdlet,
And if you need to provide credentials, you can use WMI:
$Credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
$Service = Get-WmiObject -Class win32_service -ComputerName Server -Filter 'Name = "W3SVC"' -Credential $Credentials
Try using a WMI call instead, I have found it far more reliable when working with remote servers.
$Service = Get-WmiObject -Computername $computer -Credential $credentials Win32_service -ErrorAction Continue | Where {$_.Name -eq 'IISADMIN'}

Powershell - Check on Remote Process, if done continue

As part of a backup operation, I am running the 7zip command to compress a folder into a single .7z file. No problems there as I am using the InVoke-WMIMethod.
Example:
$zip = "cmd /c $irFolder\7za.exe a $somedirectory.7z $somedirectory"
"InVoke-WmiMethod -class Win32_process -name Create -ArgumentList $zip -ComputerName $remotehost"
My problem comes in as my script continues, the 7za.exe process hasn't completed. I am then attempting to copy the item off of the remote system and it is either incomplete or fails.
Can someone point me in the direction to figure out how to identify if the 7za.exe process is still running, wait until it is dead, then proceed with the rest of my script?
I can grasp pulling the process from the remote system via...
get-wmiobject -class Win32_Process -ComputerName $remotehost | Where-Object $_.ProcessName -eq "7za.exe"}
Not sure how to turn that into usable info for my issue.
Answer UPDATE: (thx to nudge by #dugas)
This will do it with some feedback for those that need it...
do {(Write-Host "Waiting..."),(Start-Sleep -Seconds 5)}
until ((Get-WMIobject -Class Win32_process -Filter "Name='7za.exe'" -ComputerName $target | where {$_.Name -eq "7za.exe"}).ProcessID -eq $null)
You can invoke the Wait-Process cmdlet on the remote computer with the Invoke-Command cmdlet. Example:
$process = Invoke-WmiMethod -Class Win32_Process -Name create -ArgumentList notepad -ComputerName RemoteComputer
Invoke-Command -ComputerName RemoteComputer -ScriptBlock { param($processId) Wait-Process -ProcessId $processId } -ArgumentList $process.ProcessId
Since you mentioned using Invoke-Command is not an option, another option is polling.
Example:
$process = Invoke-WmiMethod -Class Win32_Process -Name create -ArgumentList notepad -ComputerName hgodasvccr01
$processId = $process.ProcessId
$runningCheck = { Get-WmiObject -Class Win32_Process -Filter "ProcessId='$processId'" -ComputerName hgodasvccr01 -ErrorAction SilentlyContinue | ? { ($_.ProcessName -eq 'notepad.exe') } }
while ($null -ne (& $runningCheck))
{
Start-Sleep -m 250
}
Write-Host "Process: $processId is not longer running"
You should be able to do it with a do... while loop that just sleeps until the process is finished.
do {
"waiting"
start-sleep 10
} while (gwmi -class win32_process -ComputerName $remotehost | Where ProcessName -eq "7za.exe")

Not able to start and stop service from remote machine

We have some winodow services on the remote machine. I am not able to start and stop that services using service controller from my machine.
You can use Powershell and supply it with the appropriate credentials:
PS C:\Users\YourUserName>$remoteComp = "remoteComputerName"
PS C:\Users\YourUserName>$svc = "Service Name"
PS C:\Users\YourUserName>$c = Get-Credential
PS C:\Users\YourUserName>$obj = (gwmi -computername $comp -class Win32_Service -computer $remoteComp -Credential $c | Where-Object { $_.Name -match "^$svc*" }
Now you can use $obj to stop and start the service
PS C:\Users\YourUserName>$obj.StopService()
PS C:\Users\YourUserName>$obj.StartService()
In addition, if you want to see the methods and properties available for $obj use this command:
PS C:\Users\YourUserName>$obj | Get-Member