What service restart first when we put 2 or more arguments (or in this same time)? - powershell

I need restart 2 services, but first vmicvss and next vss.
Get-Service -Name vmicvss, vss | Restart-Service
General services vss need vmicvss to run properly and I want know how exactly this code is execution. Is like:
Restart-Service vmicvss
Restart-Service vss
Or
in this same time or random moment.

Get-Service and Restart-Service apparently output / restart services in alphabetical order when given an array of names via parameter -Name.[1]
By contrast, providing the names / service objects via the pipeline does honor the input order:
# CAVEAT: Names passed to -Name are *sorted alphabetically*,
# so 'vmicvss' is processed before 'vss', due to coming first
# alphabetically.
Get-Service -Name vss, vmicvss | Restart-Service
# OK - with pipeline input, order is honored.
'vmicvss', 'vss' | Get-Service | Restart-Service
# OK (you don't need Get-Service in your scenario)
'vmicvss', 'vss' | Restart-Service
[1] As of Windows PowerShell v5.1 / PowerShell Core 6.2.0-preview.3; this problematic behavior is discussed in this GitHub issue.

Related

How to shutdown the computer after closing the powershell window?

I am new to powershell. I have a powershell script I've been using to backup my files. After it runs, I would like to shutdown the computer and close the powershell window. It seems I can do one or the other, but not both. So when I restart the computer, powershell complains that it was not closed properly.
How to shutdown the computer after closing the powershell window?
TIA
p.s. Contrary to popular belief, I have read the manual. However, as mentioned below, if I put EXIT before Stop-Computer, the script exits before executing Stop-Computer. If I put EXIT after Stop-Computer, powershell complains that the file was not closed properly on reboot. Either way, I lose. :(
PowerShell does provid and 'Exit', as noted in my comment. As for stopping, just put the 'Stop-Computer' cmdlet at the end of your script to shut down the computer.
Get-Help -Name Stop-Computer -examples
# Results
<#
NAME
Stop-Computer
SYNOPSIS
Stops (shuts down) local and remote computers.
----------- Example 1: Shut down the local computer -----------
Stop-Computer -ComputerName localhost
Example 2: Shut down two remote computers and the local computer
Stop-Computer -ComputerName "Server01", "Server02", "localhost"
`Stop-Computer` uses the ComputerName parameter to specify two remote computers and the local computer. Each computer is shut down.
-- Example 3: Shut down remote computers as a background job --
$j = Stop-Computer -ComputerName "Server01", "Server02" -AsJob
$results = $j | Receive-Job
$results
`Stop-Computer` uses the ComputerName parameter to specify two remote computers. The AsJob parameter runs the command as a background job. The job objects are stored in the `$j` variable.
The job objects in the `$j` variable are sent down the pipeline to `Receive-Job`, which gets the job results. The objects are stored in the `$results` variable. The `$results` variable displays the job information
in the PowerShell console.
Because AsJob creates the job on the local computer and automatically returns the results to the local computer, you can run `Receive-Job` as a local command.
------------ Example 4: Shut down a remote computer ------------
Stop-Computer -ComputerName "Server01" -Impersonation Anonymous -DcomAuthentication PacketIntegrity
`Stop-Computer` uses the ComputerName parameter to specify the remote computer. The Impersonation parameter specifies a customized impersonation and the DcomAuthentication parameter specifies authentication-level
settings.
---------- Example 5: Shut down computers in a domain ----------
$s = Get-Content -Path ./Domain01.txt
$c = Get-Credential -Credential Domain01\Admin01
Stop-Computer -ComputerName $s -Force -ThrottleLimit 10 -Credential $c
`Get-Content` uses the Path parameter to get a file in the current directory with the list of domain computers. The objects are stored in the `$s` variable.
`Get-Credential` uses the Credential parameter to specify the credentials of a domain administrator. The credentials are stored in the `$c` variable.
`Stop-Computer` shuts down the computers specified with the ComputerName parameter's list of computers in the `$s` variable. The Force parameter forces an immediate shutdown. The ThrottleLimit parameter limits the
command to 10 concurrent connections. The Credential parameter submits the credentials saved in the `$c` variable.
#>
Or use the Restart-Computer cmdlet, if that is your goal instead.
Update
Use two scripts, main and child.
# Start-Main.ps1
0..4 |
ForEach{
"Inside function... $PSItem"
Start-Sleep -Seconds 1
}
.\Start-Child
Exit
# Start-Child.ps1
'Preparing to shutdown in 10 seconds'
Start-Sleep -Seconds 10
Stop-Computer
or Using PS Jobs is another option as noted in my comment:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/start-job?view=powershell-7.2

PowerShell to stop and disable a service. Reading the servers from a TXT file

I see some questions about this topic, but I cannot get it working
Get-Service -Name Spooler -ComputerName (Get-Content c:\tmp\scripts\Servers\iservers.txt) |
Stop-Service -PassThru | Set-Service -StartupType Disabled -whatif
The code executes for each server on the txt file, and stops de service, but not disable the service.
Any help to get it work and/or Troubleshooting???
Regards.
How to approach this kind of problem
In automation, we work up to complexity, meaning you should start simply and then add on more features until you see where it breaks.
Right now, you're trying to do a bunch of operations in one single line:
Load a list of computers and
Reach out to the computers and Stop a service and
Also while doing this, set the service to not automatically start.
There are a lot of problems you can run into, like "what happens if these PCs aren't enabled for remoting", or "what if you need a different account to handle stopping or disabling a service".
When you're trying to figure it all out in one-line, you're in for a bad and frustrating time.
How to fix it
Start simply. Start with one computer that's nearby and definitely turned on.
Begin with reading a service. Can you even get this operation to run?
Get-Service -ComputerName SomePC123 Spooler
Status Name DisplayName
------ ---- -----------
Running spooler Print Spooler
If you run into an error, then first figure out how to be able to remote into that one PC and see if the Print Spooler is running. Then, you will know what steps to deploy to all of your machines to prepare them for remoting.
Then, once you can check if a service is running, you can add on the next step, try to stop the service.
So your code would start to look like this:
$computers = get-content .\someTextFile.txt
forEach($computer in $computers){
$service = Get-Service -ComputerName $computer Spooler
"status of spooler on $computer is $($service.Status), with start type of $($service.StartType)"
#todo, set start type to Disabled...
}
Eventually, you will have migrated each step out of the one-liner and you'll know where and why any given command is failing. This is the way.

Using Powershell to pull services on multiple domain computers

My code currently is:
$Workstationlist=get-adcomputer -filter * -searchbase 'OU=Workstations, DC=example, DC=com' -SearchScope 2 | foreach {$_.Name}
foreach($workstation in $Workstationlist){
get-service -ComputerName $workstation -name wauaserv
}
It seems to pulling service statuses from the array that is being parsed by the foreach method, but after a few values are returned it will spit this error message in between which seems to point at the location I saved the script
Running wuauserv Windows Update
Stopped wuauserv Windows Update
Running wuauserv Windows Update
Stopped wuauserv Windows Update
get-service : Cannot find any service with service name 'wuauserv'. At
\locationIsavedthescript
The idea is that I will stop the wauaserv service on all workstations in the domain, I was then going to add lines to delete everything from the \windowsdistrobution\ folder. And then restart the service. This effectively kills any downloading pending install update. I can drop $workstation into a ls snippet easy enough but pulling services doesn't seem to work quite as clean. Not sure why it is point the get-service to the location that I saved the script.
Any ideas and explanations as to how to accomplish what I'm shooting for a bit more cleanly or at least hide the erroneous output since the command IS running against the array.
I hope this made sense to someone out there.

Command to query services

I wrote a powershell command to audit services in HyperV HV's and
$Auditservices = get-service -computername $ComputerName -name "*iscsi*","*winrm*","*scvmm*","*vmms*","vss"| Select-Object Status, Name, MachineName
And output for the same is showing like below
MSiSCSI SCVMMAgent vmms vss WinRM Running Running Running Running Running
Is there anyway we can change the output to this format ?
MSiSCSI,Running
SCVMMAgent,Running
vmms,Running
vss,Running
WinRM,Running
If you really want to get output exactly as you've described, you'll need to create some strings:
$Auditservices | Foreach-Object {"$($_.Name),$($_.Status)"}
You might instead actually want it in CSV format? If so, pipe it to Export-CSV

Powershell: Re-create RDS Remote Apps by Looping?

I'm stumped. I can usually take the output of one powershell command and use it as the input to another powershell command. For example:
Get-Mailbox | Set-Mailbox -MaxSendSize 40MB
This will loop through every mailbox and then set the maximum send size to 40 MB in Exchange 2007.
...but the same doesn't work with get-rdremoteapp and new-rdremoteapp.
Get-RDRemoteApp | new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local
The goal of this command is that we are preparing to Migrate from a Windows 2012 RDS environment on virtual servers to a Windows 2012 R2 environment on physical servers.
On the virtual 'edge' server, I should be able to get all the RD Remote Apps, loop through them, and then use the 'new-rdremoteapp' command to create them on the new 'edge-1' server.
What actually happens is the command runs and creates the 1st remote app, then exits without an error. It doesn't process the apps in the list.
I think I need to use foreach-object, but after reading the docs and playing around, I can't seem to get it to work.
I couldn't find an easy out. I had to specify a bunch of parameters like so:
Get-RDRemoteApp | foreach-object -process {new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local -displayname $_.displayname -filepath $_.filepath -alias $_.alias -commandlinesetting $_.commandlinesetting -usergroups $_.usergroups}
Time to find a job that has more bash scripting... ;)