Why would Get-Service not find the service with powershell - powershell

I am having problems with a powershell script.
I wrote a script that would search for a windows service with a specific name, and it would Stop or Start this service.
It works when I run it on a server which I log into with a service account that I know that can access the service console. However when it runs off of my build server, the script is no longer able to find the services. I tried giving the service account that runs script the same privaledges as the other service account but that doesn't seem to work.
[System.ServiceProcess.ServiceController]$service = Get-Service -Name $ServiceName -ComputerName $Remoteserver -ErrorAction SilentlyContinue
That is the line that is not longer able to find the service. What am I doing wrong. Is there a way to impersonate a user that can find the service? Any help would be appreciated.

You could try supplying the credentials of the service account using the -Credential parameter. However, since you imply that it used to work with the account that runs the script remotely and no longer does, I think a more likely culprit is that $ServiceName used to only match one service on the target computer, and now there is another service whose name matches that string. If more than one service matches the -Name parameter, Get-Service returns an array of ServiceController objects.
Try running it without ErrorAction -SilentlyContinue. If you get the following error message, then that's what's happening:
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.ServiceProcess.ServiceController".
If you get a different error message, please add the full error message to the question.

Related

Passing active powershell Session to background jobs

I am writing a powershell script to manipulate Exchange Online mailboxes.
I want this script to run with background jobs in parallel, so I'm trying to use PoshRSJobs (https://github.com/proxb/PoshRSJob) to create the jobs.
My code is:
Connect-ExchangeOnline -Credentials ...
Start-RSJob -ModulesToImport ExchangeOnlineManagement -Throttle $ProcesosConcurrentes -InputObject $jobs -ScriptBlock {
./migra_buzon.ps1 ...
}
Where:
$jobs is an arraylist where I have the parameter of the mailboxes I want to operate with
migra_buzon.ps1 is another powershell scripts that operates over one specified mailbox
The problem I have when I run this way is that in the jobs I have the error:
The term 'Add-MailboxPermission' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Although other commands like Get-EXOMailbox are working correctly.
Looking for help I found that the problem can be related with the session, so I changed my code to:
Connect-ExchangeOnline -Credentials ...
Start-RSJob -ModulesToImport ExchangeOnlineManagement -Throttle $ProcesosConcurrentes -InputObject $jobs -ScriptBlock {
$o365session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid" -Credential $(Import-Clixml $Using:ExchangeCredentials) -Authentication "Basic" -AllowRedirection
Import-PSSession $o365Session -CommandName #('Add-MailboxPermission', 'Get-MailboxPermission')
./migra_buzon.ps1 ...
}
In this case, the problem I have is with the Exchange connection. After running a few jobs I'm getting the error:
[outlook.office365.com] Processing data from remote server outlook.office365.com failed with the following error message: Client did not get proper response from server. For more information, see the about_Remote_Troubleshooting Help topic.
Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for the argument, and then try running the command again.
So my question is, what is the right way to run background jobs sharing the connection got in the main process?
Thanks
PS: I first tried to run jobs with Start-Job, but with this the problem is that each background job needs its own connection, so I got and maximum number of connections exceeded. And this is the reason I changed my code to Start-RSJob
It appears that you are hitting Exchange Online throttling limits.
If that indeed the case, you can try the following method.
How to relax PowerShell throttling
There is a relatively new customer facing way to increase or update PowerShell Throttling Policies.
Go to Microsoft 365 admin center.
Validate that you are logged in with the user that has the correct role assignment.
Click on the Need Help? Widget in the bottom right corner
Graphical user interface
Type Exchange PowerShell throttling in the search box and select “Temporarily update throttling policies for a migration”. Keep in mind that this is only applicable for 90 days. After 90 days, the throttles will return to back to the default values for that tenant.
MachSol offers Tenant management using a job engine, that allows you to do multiple operations using front-end and let the jobs handler take care of processing in background. You can give it a try:
https://www.machsol.com/machpanel-automation-for-microsoft-CSP-partners/

Powershell - Pass in and execute string without using WinRM

I am trying to utilize a custom PS function that will accept a powershell command as a string parameter and execute/store the results in a variable within the function itself to be referenced later. After doing some research, I found a way of doing this by passing in "Get-WinEvent" as a string variable to the function and then within the function converting that variable to a scriptblock like so:
$PowershellQueryScript = [Scriptblock]::Create($PowershellQuery)
Once I did that, I called the variable in my foreach loop and stored the results like so:
$myResults = Invoke-Command -ComputerName $server -ScriptBlock $PowershellQueryScript
Now the error I receive is in regards to WinRM not being enabled ("Connecting to remote server myServer failed with the following error message : WinRM cannot process the request.") and unfortunately I do not think I will be allowed to make this settings change in production. If I were to call this command directly from my server -> production without utilizing Invoke-Command then everything works as expected as I think it does not have to create a remote PS session on the remote server so WinRM is not required.
Are there any other workarounds for allowing a user to call my function with a string and have that string be executed in the function itself WITHOUT having to enable WinRM?
After some more research, I found out WinRM was already enabled and the proper firewall settings were already configured as well. The problem was that I was using cnames and not FQDNs (Fully Qualified Domain Names) so the DNS was not resolving properly. Issue is resolved by converting cname to a value that can be resolved:
$ServerFQDN = [System.Net.Dns]::GetHostEntry([string]$ServerCname).HostName

Get Associated Application of a Disabled / Stopped Service

Problem
I am working with a PowerShell script to skim through a lists of known application services and, for any that are disabled, the script is expected to uninstall them. I have been researching how to get the application name/path of a target service, but failed to find anything suitable to my needs. I had tried working with Get-Service in hopes of that getting me what I need, but was not able to get the desired results.
Question
How do I get the associated application of a target service that is currently stopped or disabled using PowerShell?
PS: Please understand that PowerShell is a requirement of this.
The running state of the service shouldn't really impact what information you get back. However Get-Service doesn't give you all of the configuration info for a Service, in particular the Path of the process being invoked.
To get that you can use Get-WMIObject Win32_Service. For example:
Get-WMIObject win32_service | Where {$_.name -eq 'wuauserv'} | Select *
This returns a PathName property amongst others that I think you will find useful.

Getting error when trying to start windows service through Powershell

So I am trying to use Powershell to start a windows service. I have the service installed just fine, but when I call Start-Service -Name $name I am recieving the following error.
Start-Service : Service 'IncidentManagementService (IncidentManagementService)' cannot be started due to the following error: Cannot start service IncidentManagementService on computer '.'.
I have powershell running as an Administrator and I also tried going under the properties of the .exe file and checking "run as admin" to no avail.
If anyone could give me a clear reason as to why the service is not starting it would be much appreciated.
In my case the service is disabled... so is the reason I am getting that error.

PowerShell Stop-Service/Start-Service not working on a specific server

I have three servers, let's call them Deploy1, Deploy2, Target.
All servers are running Windows Server 2008R2, fully updated.
A domain user, admin1, is configured as administrator on all servers, and this is the user I'm running all the commands with.
The following command works on Deploy1:
Get-Service "MyService" -ComputerName Target | Stop-Service
When running the same command on Deploy2, the command fails with the following message:
Cannot find any service with service name 'MyService'.
On Deploy2, the following command works, and displays the service and its status.
Get-Service "MyService" -ComputerName Target
Now, I know there are other ways to stop/start services via PowerShell, but I like this one as it automatically waits for the server to actually stop/start.
So what could be wrong with Deploy2?
Powershell v2.0 has a bug (feature?) in how the object returned by Get-Service is implemented. It does not actually set the ComputerName property correctly. Because of this, it can only affect local services. If you upgrade to Windows Management Framework 3.0 (and consequently Powershell v3) the bug is fixed and will work correctly.
Does this work? If not, is there an error produced?
(Get-Service "MyService" -ComputerName Target).Stop()