Reading event log remotely with Get-EventLog in Powershell - powershell

I've a powershell script which runs on server(test-server) and reads the log file of his client(DC1).
Both sides can ping to each other.
On both sides, firewalls are disabled.
Remote Desktop and Remote Assistance are enabled on DC1.
Get-EventLog System -ComputerName test-server -Source Microsoft-Windows-Winlogon # WORKS
Get-EventLog System -ComputerName DC1 -Source Microsoft-Windows-Winlogon # DOESN'T WORK
I run this script on test-server. As you see when I read the local log file on test-server it works fine but if I try to read the log file of DC1 remotely I get the error "Get-EventLog : The network path was not found.".
Screenshot of the error:
How can I avoid this error and read the log file of DC1 from test-server with using Get-EventLog?

#Lars Truijens's suggestion solved my issue. But other suggestions are also important to check.
So, here is the checklist if you get this kind of error when you try to get log files remotely:
Disable or set firewall settings on both sides.
Enable Remote Desktop and Remote Assistance on client machine.
Can you ping to the client machine?
Run dir \\dc1\c$ to see that you are allowed to reach to the
harddisk. (#Shay Levy's suggestion)
Run Get-Service -ComputerName YOURCOMPUTERNAME to see that you are
allowed to reach to the services. (#Shay Levy's suggestion)
Start the Remote Registry service. (#Lars Truijens's suggestion and
this made it work for me)
Here is the screenshot of this solution:

Starting the RemoteRegistry service did not help in my case.
Apparently, there is a difference between the remoting that is accessed via the ComputerName parameter in some cmdlets such as Get-Service and the newer form of remoting accessed with cmdlets such as Invoke-Command.
Since traditional remote access is implemented by individual cmdlets,
it is inconsistent (uses different techniques and demands different
requirements) and available only in selected cmdlets. The technology
used for remote access can vary from cmdlet to cmdlet and is not
readily known to you. Each cmdlet uses whatever remoting technology
its author chose. Most cmdlets use Remote Procedure Call (RPC), but
might also require additional services and settings on the target
system.
Beginning in Windows PowerShell 2.0, there is an alternate and more
universal way of accessing remote systems: Windows PowerShell
Remoting. With this type of remoting, Windows PowerShell handles
remote access for all commands. It transfers your commands to the
remote system using the relatively new and highly configurable WinRM
service, executes the code in a separate session that runs on the
remote system, and returns the results to the calling system.
http://powershell.com/cs/media/p/7257.aspx
When I swapped from this command
get-eventlog -LogName System -computername <ServerName>
to this
invoke-command {get-eventlog -LogName System} -ComputerName <ServerName>
I no longer got the following error
get-eventlog : The network path was not found.

Related

Access to remote machines via Terminal. Power Shell

I have some machines with Windows and with installed VNC.
I can connect to them from my local computer via UltraVNC.
But now I need to connect to those machines via some terminal. Command line, or Windows Power Shell.
All I know are IPs and password to connect via UltrVNC.
Do you have aby idea if it is even possible and if yes, how to do that?
I have o lot of that machines and need to write some script to chec some files on them.
If you only have VNC access, then you may be able to use the vncdotool python module to basically emulate mouse+kb control over VNC.
Here are the other (built-in) console methods for windows remote access, using powershell for example:
WinRM: For opening a full remote session: Enter-PSSession -ComputerName myServer
WMI (DCOM/RPC): For querying any system information, and limited remote ability to run commands/start processes: Get-WmiObject -Class Win32_OperatingSystem -ComputerName myServer
RPC: More limited, lightweight way to remotely call specific functions/procedures: Get-Service spooler -ComputerName myServer | Restart-Service
Or other services that can be installed like SSH/SFTP/FTP.

PowerShell: How to run a powershell script on a remote machine using WMI

To be specific: I want to run a powershell script on a remote windows server, but I can connect to this server using WMI only.
I used, for example, Get-Wmiobject to get some data like the running processes, but I failed after a lot of searching, to find a way to run a powershell script block on this remote one. One of the commands that I found is Invoke-Command but this one uses the winRM which is not opened to that remote server.
So, it is NOT allowed to run a powershell script on a remote server using WMI? I didn't find a clear and a direct answer for that.
tl;dr
Consider using psexec as an alternative to PowerShell remoting for executing arbitrary commands.
The list of PowerShell commands that support targeting remote machines without relying on PowerShell remoting is limited (see below); they may all be WMI-based (I'm not sure), and they're focused on retrieving and manipulating remote resources (as WMI is in general) rather than providing the ability to execute arbitrary commands.
Update: Alberto Varga's helpful answer points out that the Win32_Process WMI class's .Create method indeed does allow creation of arbitrary processes;
the documentation of PowerShell's Invoke-WmiMethod cmdlet even contains an example.
By contrast, Invoke-Command, which does offer the ability to execute arbitrary commands, does use PowerShell remoting, as you've discovered, which requires the WS-Management protocol, as implemented by Microsoft's WinRM service, among other prerequisites -
see Get-Help about_Remote_Requirements.
The most generic of the non-remoting commands listed below is Invoke-WmiMethod, which provides open-ended access to WMI classes and their methods.
Note, however, that Microsoft recommends using the more recent *-Cim* cmdlets such as Invoke-CimMethod in the interest of cross-platform support, and that these CIM-compliant cmdlets again rely on WS-Management (WSMan) standards, as PowerShell remoting does.
List of PowerShell cmdlets that support targeting remote machines via -ComputerName without using PowerShell remoting, as of PSv5.1 (see Get-Help about_Remote_FAQ for background info):
Add-Computer
Clear-EventLog
Get-EventLog
Get-HotFix
Get-Process
Get-Service
Get-WmiObject
Invoke-WmiMethod
Limit-EventLog
New-EventLog
Register-WmiEvent
Remove-Computer
Remove-EventLog
Remove-WmiObject
Rename-Computer
Restart-Computer
Set-Service
Set-WmiInstance
Show-EventLog
Stop-Computer
Test-Connection
Write-EventLog
This can be easily done. What you want is Win32_Process and method called Create. This allows you to spawn processes on remote machines 2K3 and higher.

PSexec vs Built-in Windows

So, I'm writing tools in PowerShell to execute files on remote computers. I was initially using PSexec but switched them to .net framework using win32_process. When I ran an install file on the remote machine using win32_process, it failed. And after trying gwmi win32_process on the remote machine, that failed. So accessing the wmi objects is probably the problem. Anyway! I ended up using PSexec and it succeeded, and i verified that it did. But, that got me thinking about how PSexec connects to the remote machine, and I was wondering if anyone on here knew either how I could look at PSexec source code or if someone flat out knew how it connects and executes.
I couldn't find anything on it online, just a bunch of articles about what it can do. Maybe I just suck at researching though.
I have done this using the Invoke-WmiMethod cmdlet against remote machines. You need to include any switches in your executable path but the below code sample should get you there assuming you have appropriate permissions on the local / remote hosts.
See https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/invoke-wmimethod?view=powershell-5.1 for more details on the cmdlet.
#local path on the remote machine that will be run including any switches needed
$exePath = "c:\mypath\myfile.exe -s -norestart"
# Use FQDN or IP if netbios name is not reachable
$server = "myserver"
try {
Invoke-WmiMethod -ComputerName $server -Class win32_process -Name create -ArgumentList $exePath -ErrorAction Stop | Out-Null
}
catch {
Write-Host "Failed to execute program on $server. Error Details: $_.Exception.Message" -ForegroundColor Red
}
I can't speak to how PSExec works for you to compare but this method has worked for me in the past executing applications on remote hosts using only native PowerShell.

Windows - remotely running executable or cmd using WMI or powershell, and logging the output

This is incredibly difficult to do. I can't believe it. It should be so easy.
Anyway, using WMI (with both vbscript and perl) I'm able to start a process on a remote machine that runs a .exe, but I cannot get the output to write to a log. This is driving me nuts. I have to use WMI or powershell because I can't install anything additional on the remote machines, which are all Windows 2003 or newer. I also cannot assume that powershell remoting is enabled on all target machines, so I may not even be able to use powershell. This can cause a problem with powershell.
Here is what I'm trying to do in psuedo code:
servers = server1, server2, server3
for each server in servers
run command on remote server >> log.txt
next
I'm assuming you have powershell remoting enabled on all the servers and that you want the results saved in a local log file (ie not on each server)...
$Servers = "server1", "server2","server3"
Invoke-Command -ComputerName $Servers -ScriptBlock { ping.exe www.stackoverflow.com } >> c:\localfile.txt
This also assumes that your exe outputs to stdout, I think there will be issues capturing other streams.

Execute remote quiet MSI installs from Powershell

I am trying to use the Invoke-Command powershell cmdlet to install a MSI installer. From within powershell on the local machine and from the proper directory, the following works:
./setup /quiet
The following does not seem to work:
$script =
{
param($path)
cd "$path"
& ./setup /quiet
return pwd
}
return Invoke-Command -ComputerName $product.IPs -ScriptBlock $script -Args $sourcePath
For test purposes I am working on the local machine passing in "." for the -ComputerName argument. The paths have been verified correct before passing in to Invoke-Command, and errors generated on different versions of this code indicate the paths are correct. I have also tried with and without the "& " on the remote call to setup. Other Invoke-Command calls are working, so I doubt it is a permissions issue. I have verified that the return from the pwd call is the expected directory.
How do I get the install to work?
What error (if any) are you receiving? Unfortunately, you must run the shell as admin on your local machine to be able to connect to your local machine with invoke-command or any WINRM based command that requires administrative privilege (this is not a requirement when connecting remotely).
When connecting to loopback, I believe it is unable (for some security reason) to enumerate groups and determine if you are in an admin enabled AD or local group, which is how it auto elevates when invoking on a remote machine. The only solution may be to have a conditional which checks for localhost and if so, don't use the -ComputerName parameter.
This GitHub Issue covers it
You might try using Start-Process in your script block:
cd $path
start-process setup.exe -arg "/quiet"
Not sure if you will want or need to wait. Look at help for Start-Process.
I have had weird issues when trying to remotely execute a script on a local machine. In other words, remote powershell to the local machine. It comes back with an error that seems to say that PowerShell remoting is not enabled on the machine, but it was. I can run the script remotely from another machine to the target, but when using remoting to the same box, the issue crops up.
Verify that the WinRM service is running.
Verify powershell remoting has been enabled as in Enable-PSRemoting -force.
Verify your powershell execution policy is loose enough as in Set-ExecutionPolicy Unrestricted, for example. If the policy was set to RemoteSigned, this might be the problem.
You might also want to verify the user you are running the script as (locally, but using remoting) has privileges to "log on as a service" or as a batch job. Just guessing there, if the above list doesn't solve anything.