poshsecurity / Posh-SYSLOG

Send SYSLOG messages from PowerShell
http://poshsecurity.com
MIT License
92 stars 19 forks source link

This is not working on powershell core on linux due to Get-CimInstance #21

Closed rscottwatson closed 5 years ago

rscottwatson commented 5 years ago

Prerequisites

Put an X between the brackets on each line to confirm you have completed them:

Describe the bug

PS /home/scottw/db_powershell> Send-SyslogMessage -Server localhost -Message "Test from POWERSHELL" -Severity Informational -Facility local5
Get-CimInstance : The term 'Get-CimInstance' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At /usr/local/share/powershell/Modules/Posh-SYSLOG/4.0/private/Get-SyslogHostname.ps1:42 char:30
+     $Win32_ComputerSystem =  Get-CimInstance -ClassName win32_compute ...
+                              ~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Get-CimInstance:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

The variable cannot be validated because the value  is not a valid value for the Hostname variable.
At /usr/local/share/powershell/Modules/Posh-SYSLOG/4.0/public/Send-SyslogMessage.ps1:282 char:13
+             $Hostname = Get-SyslogHostname -Socket $NetworkClient.Cli ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : MetadataError: (:) [], ValidationMetadataException
+ FullyQualifiedErrorId : ValidateSetFailure

To Reproduce Run the above on an installation of Powershell core on linux

Expected behavior A message show up in the local log files.

Screenshots or Transcripts If applicable, add screenshots or PowerShell transcripts to help explain your problem. You can use Start-Transcript and Stop-Transcript to record the steps you have performed.

System Details

ModuleType Version Name ExportedCommands


Manifest 6.1.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty...} Manifest 6.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...} Script 1.1.7.2 PackageManagement {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...} Script 4.0 Posh-SYSLOG Send-SyslogMessage Script 1.6.7 PowerShellGet {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...} Script 2.0.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler...}



**Additional context**
Add any other context about the problem here. Is there any other information like system configuration or data that might help us understand the problem.
krmxd commented 5 years ago

A quick fix could be: if (!$isWindows) {$hostName = System.Net.Dns]::GetHostByName((hostname)).HostName}

kjacobsen commented 5 years ago

That will only work on PS Core as $isWindows on PowerShell 5.1 will return $null

Perhaps this might be better:

if ($isLinux) {$hostName = [System.Net.Dns]::GetHostByName((hostname)).HostName}
else { 
    # use existing code
}
ThreepE0 commented 5 years ago

Is there any reason to use this instead of built-in syslog in linux?

kjacobsen commented 5 years ago

Cross platform scripts?

ThreepE0 commented 5 years ago

I’d think it’d be easier/better/cleaner to build the “cross-platform” part of it into the script. You can see some of the solutions being suggested here include detecting OS. If you did that in the script and selected your version of syslog there, I think that’d be cleaner. If linux, use syslog. If windows, use posh. Especially if this is your only requirement for powershell in linux, though I’m not sure it is. Just trying to understand the use case here. This isn’t my repo so I have no horse in the circus haha. Does that make sense?

kjacobsen commented 5 years ago

Code base also doesn't work due to Get-NetworkAdapter.

Need to think through this logic and test it thoroughly.

kjacobsen commented 5 years ago

This isn't just a linux thing, doesn't correctly work on 6 on Windows either.

I think I have a cross platform fix, will post on a branch shortly.

kjacobsen commented 5 years ago

Hit a bit of a wall trying to clean up the logic.

We can determine if a FQDN has been configured at a global level (Windows Domain or Linux), via:

$ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
$ipProperties.DomainName

This doesn't pick up if there is a NIC based domain name specified however. Something that has been overlooked. I think this one is easy to fixed.

The next issue is if no domain name has been specified (just a hostname), we need to confirm if the IP address for that adapter is static or dynamic.

Looking at possible replacements for the Get-NetworkAdapter call. The obvious one is [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() unfortunately that doesn't work correctly on WSL under PowerShell 6.2.1 (due to this issue in DotNetCore), but it partially works under 7 preview.

kjacobsen commented 5 years ago

I will go ahead and code the solution up, however I am not sure how to resolve the WSL issues.

kjacobsen commented 5 years ago

Just spent 4 hours replacing Get-NetworkAdapter...when I already did that....sigh....

kjacobsen commented 5 years ago

This has now been fixed as of release 4.1