Schedule.Service erroring out while connecting to localhost - powershell

I have a PowerShell script that connects to a list of servers, and queries that scheduled tasks. (Something similar to https://community.spiceworks.com/scripts/show_download/2094-get-scheduled-tasks-from-a-computer-remote-or-local) It used to work fine on a Windows 2008R2 server. However, on a new Windows Server 2012 R2 server, it is giving the below error. Strange thing it only happens when connecting to the local machine, no errors to remote servers. And it doesn't raise any errors when running under my account using administrative privileges.
https://www.powershellmagazine.com/2015/04/10/pstip-retrieve-scheduled-tasks-using-schedule-service-comobject/
This article says
Unfortunately, unlike the Get-ScheduledTask cmdlet using this COMObject requires an elevated PowerShell console with administrative credentials.
But the script used to work just fine on Windows Server 2008 R2 servers.
Is there anything that can be tweaked to make the script work on 2012 R2 servers?
Exception calling "Connect" with "1" argument(s): "Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At C:\scripts\CheckSchedulers\CheckSchedulers.ps1:20 char:10
+ ($TaskScheduler = New-Object -ComObject Schedule.Service).Connect($curSe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
The error is raised by my code, using the code from spiceworks, it is reproducible.

You're creating a Schedule.Service object, assign it to a variable, and then try to call a Connect() method on the result of that assignment. I would not expect this to work on any Windows or PowerShell version, and if it did on Server 2008 R2 that's most likely just incidental.
You need the Schedule.Service object in a variable (because you're going to need it for other operations as well), and you must call Connect() on that object, so you need to do this in two steps:
$TaskScheduler = New-Object -ComObject 'Schedule.Service'
$TaskScheduler.Connect($servername) # connect to remote Task Scheduler
If you're connecting to different servers in a loop you can re-use the object and just Connect() to the next server.
For connecting to the local Task Scheduler service just remove $servername and call the method without argument:
$TaskScheduler.Connect() # connect to local Task Scheduler

Related

Why do I get a "Get-WindowSize" not implemented error when using the PowerShell call Get-Service on a remote machine?

I have a Windows 10 host machine that connects to a Hyper-V Windows 10 VM hosted on the same box.
I've been following along the Pluralsight PowerShell tutorial.
I'm trying to get the services available on a remote computer.
I can start a session on the remote computer with the following command:
Enter-PSSession -ComputerName Client1 -Credential username
Once the session has started and I am connected, I attempt to call Get-Service to identify the services on the client computer.
[Client1]: PS C:\Users\username\Documents>Get-Service
When I run the above command, I get the following error message:
Remote host method get_WindowSize is not implemented.
+ CategoryInfo : ResourceUnavailable: (:) [out-lineoutput], PSRemotingDataStructureException
+ FullyQualifiedErrorId : System.Management.Automation.Remoting.PSRemotingDataStructureException,Microsoft.PowerShell.Commands.OutLineOutputCommand
I am running the same version of PowerShell on the host and client machines (5.1.18362.145).
I assume that somehow this is an issue on the client machine?
[Client1]: PS C:\Users\username\Documents>Get-Service | out-string
That should work, maybe a bug with PowerShell or new version of Windows 10
Other link : https://social.technet.microsoft.com/Forums/en-US/67142783-2acd-4d54-aef2-8d89d71457c5/powershell-remoting-broken-in-windows-10-1903?forum=winserverTS
"Remote host method get_WindowSize is not implemented."
This happens to all Remoting Sessions started With Powershell_ISE on the Client-Side.
The workaround with Out-String sucks, it destroys the Result-Object of that call.
Best fix so far is either using not ISE or embed your remote Procedure in a Script and call it with Powershell.exe
Really annoying...and not fixed by now.
Workaround Example: Instead of using enter-pssession and then asking for a result of running services, you could use: $YourServices=Invoke-command -ComputerName <computername> -ScriptBlock {get-service}. Then you have all Service-Stats in your Object $YourServices.

Powershell script fails during remote execution but works locally

I am attempting to execute the code below. The errors are self-explanatory but only occur when run remotely. When run locally, all the code works and I can verify that they have the desired effect by pulling content from a web server that requires Tls12 and receiving an error when I have not changed the security protocol.
$tls12 = [Enum]::ToObject([Net.SecurityProtocolType], 3072)
[Net.ServicePointManager]::SecurityProtocol = $tls12
When run on the server, they execute flawlessly. When run remotely via Invoke-Command I receive this error.
Exception setting "SecurityProtocol": "The requested security protocol
is not supported."
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
+ PSComputerName : servername
Alternatively, this line of code which is fundamentally the same.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
This also works when run on the server directly but results in this error when run remotely.
Exception setting "SecurityProtocol": "Cannot convert null to type
"System.Net.SecurityProtocolType" due to invalid enumeration values. Specify one of the following enumeration values and
try again. The possible enumeration values are "Ssl3, Tls"."
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
+ PSComputerName : servername
The remote server Windows Server 2008 R2 and is running powershell 2.0. The latest Framework version installed is 4.5 release 378389. The machine I am executing from is Windows 10 running powershell 5.0 and Framework 4.6.2 in case it matters.
This is the code I am using to execute it remotely.
$webSession = New-PsSession -ComputerName servername
$cmd = {
#$tls12 = [Enum]::ToObject([Net.SecurityProtocolType], 3072)
#[Net.ServicePointManager]::SecurityProtocol = $tls12
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
}
Invoke-Command -ScriptBlock $cmd -Session $webSession
remove-pssession $webSession
If anyone has an idea or suggestion, I would greatly appreciate the help.
[Note: The remainder of this answer SHOULD be true, but ISN'T: Even though the Tls12 value is not defined in an interactive PSv2 session, it can be assigned and takes effect using the OP's workaround, [Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([Net.SecurityProtocolType], 3072); by contrast, trying the same thing via PS remoting, using Invoke-Command -ComputerName fails for him. Upgrading PowerShell on the target machine may still be the answer, but this answer offers no explanation of the behavior.]
As Sambardo notes in a comment on the question, the symptom implies that the remote target machine doesn't support the Tls12 value:
PSv2 invariably uses a 2.0 version of the .NET framework, where TLS 1.2 is not supported - irrespective of the presence of newer .NET frameworks on a given machine.
If you run [enum]::GetNames([Net.SecurityProtocolType]) on a machine with PSv2 , you'll see that only the following values are supported:
# PSv2
> [enum]::GetNames([Net.SecurityProtocolType])
Ssl3
Tls
So the answer is to upgrade PowerShell on the remote machine.
As an aside: PowerShell's great flexibility around type conversions allows you to simply use string representations of [enum] values; e.g., the following 2 statements are equivalent:
[Net.ServicePointManager]::SecurityProtocol = 'Tls'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls

Querying AD from Powershell

I'm new to Powershell and AD. I have troubles using AD module for PS. I get the following error using any command:
Get-ADDomain : Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services
running.
At line:2 char:1
+ Get-ADDomain -Current LocalComputer
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (lon.intensive.int:ADDomain) [Get-ADDomain], ADServerDownException
+ FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADDomain
What is interesting I'm able to use ADExplorer and see domain, users and all their attributes. How does ADExplorer differ from scripts in Powershell?
What operating system are your domain controllers? The AD cmdlets have to connect to a domain controller that's running Active Directory Web Services. This is automatic on Windows 2008 R2 and newer domain controllers, but on Windows 2008 and Windows 2003 you need to install it separately. Ideally, you've gotten rid of all of your Windows 2003 DCs because it's out of support. 2008 is getting pretty old too. But if you can't, then you should install ADWS on all of the downlevel DCs so that you can use the AD cmdlets.
You can use Get-ADDomainController-Discover -Service ADWS to find a DC running it. You could use the result of that call in the -Server parameter of the rest of the AD cmdlets (or use $PSDefaultParameterValues to set it once in the script). But if that doesn't return any DCs, then you need to install ADWS.

How to Specify the Password to repadmin.exe via Remote PowerShell Session

I have some issues with repadmin.exe utility
I have the following setup:
Windows Server 2012R2 with ADDS installed running inside of VMWare VM
Windows 8.1 Pro (host for VMware, my home desktop). My host is NOT a part of the domain
I do the following:
Open PowerShell ISE on my Windows 8.1 and establish remote connection to my DC (PowerShell ISE -> File -> New Remote PowerShell Tab)
Once I`m connected remotely to DC I run the following command
repadmin.exe /syncall
and get the following error:
CALLBACK MESSAGE: Error contacting server ad864315-1f78-4266-a7c2-2d6f9cde2f15._msdcs.arvo.local (network error): 5 (0x5):
Access is denied.
CALLBACK MESSAGE: Error contacting server a5904e4b-dff2-4b75-b856-45593a48d84e._msdcs.arvo.local (network error): 5 (0x5):
Access is denied.
SyncAll exited with fatal Win32 error: 8440 (0x20f8):
The naming context specified for this replication operation is invalid.
I found here http://technet.microsoft.com/de-de/library/cc811552%28v=ws.10%29.aspx that is is possible to specify username and password for repadmin using /u: and /pw: keys. Besides it is possible to pass the password using 2 methods - either specify it explicitly in command line or put * (asterisks) and I will be prompted to enter the password. The second option is more preferable.
So I can do ether this way (specify the password in command line):
repadmin.exe /u:domain_name\user_name /pw:p#ssw0rd /syncall
or use asterisks and enter password after this command:
repadmin.exe /u:domain_name\user_name /pw:* /syncall
Asterisks works locally in PowerShell on the server, but if I run it using Remote PowerShell Session, I get the following error:
repadmin : Password: Failed to query the console mode.
+ CategoryInfo : NotSpecified: (Password: Faile...e console mode.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Is there any workaround? I would not specify the password clearly in command line as it is not secure.
Thanks!
You might try something like this inside the remote PowerShell session:
$MyCreds = Get-Credential
Start-Process -FilePath repadmin.exe -ArgumentList "/syncall" -Credential $MyCreds
That way, you could leverage the security of PowerShell's credential management and just run the process under an account that has access to perform the replication.

Random errors while doing Enter-PSSession in powershell

I have setup lots of Powershell scripts on my WIndows 2008 R2 server. The scripts do lots of processing (data crunching, executing SQLCMD.exe, bcp.exe etc). All of these scripts work without issues.
I am trying to call and execute the scripts from a remote laptop (within the same network) using the following command:
Enter-PSSession -ComputerName sun -ConfigurationName myprofile
The "myprofile" currently has just one function that will change directory to c:
This allows me to execute the scripts from my local laptop, however, they "run" on the server. That is my understanding.
However, I have not seen any scripts execute fully. At random intervals, the scripts fail with the below error messages... Once again, I have never seen these errors when I am trying to run the scripts on the server itself.
Any inputs on how to "fix" these errors? Any settings that I need to do on the "client" in terms of memory allocation?
a.
Processing data for a remote command failed with the following error message: Not enough storage is available to complete this operation. For more information, see the about_Remote_Troubleshooting Help topic.
b.
Get-Content : Exception of type 'System.OutOfMemoryException' was thrown.
At E:\automation\mssql-upload.ps1:144 char:14
+ (get-content <<<< $PipeFile -ReadCount 1000) | set-content $FinalFile
+ CategoryInfo : InvalidOperation: (:) [Get-Content], OutOfMemoryException
+ FullyQualifiedErrorId : ProviderContentReadError,Microsoft.PowerShell.Commands.GetContentCommand
c.
[Microsoft] [ODBC Driver Manager] Driver's SQLAllocHandle on SQL_HANDLE_ENV
d.
Processing data for a remote command failed with the following error message: The WSMan provider host process did not return a proper response. A provider in the host process may have behaved improperly. For more information, see the about_Remote_Troubleshooting Help topic.
It is likely your remote session is bumping up against the WS-Man quota MaxMemoryPerShellMB. You can see the current value by executing this command on the remote machine:
Get-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB
You can set a new value like so:
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 512 -Force
This sets the value at 512MB. Set it to a value that works for your application.