CmdLets in the NetTCPIP & other Net* modules are not available cross-platform.
My use-case: we use powershell + netCore as a cross-platform develop & deploy solution. (It's great!)
If I might offer an order of priorities based on that use-case, I would prioritise
Rationale: In container and serverless application/service deployment, the ability (and hence the need) to mutate hardware and security configuration is limited; but the need to inspect network configuration does not go away.
So top of my list are:
Get-NetIPAddress
Test-NetConnection
Get-NetIPConfiguration
Get-NetIPInterface
Resolve-DnsName
Find-NetRoute
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.1
PSEdition Core
GitCommitId v6.0.1
OS Darwin 17.4.0 Darwin Kernel Version 17.4.0: Sun Dec 17 09:19:54 PST 2017; root:xnu-4570.41.2~1/RELEASE_X86_64
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
> $PSVersionTable
PSVersion 6.0.0-rc
PSEdition Core
GitCommitId v6.0.0-rc
OS Linux 4.4.51-40.58.amzn1.x86_64 #1 SMP Tue Feb 28 21:57:17 UTC 2017
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Many if not all of the net* modules are based on CIM classes that are only available on Windows 8 and later. Either those CIM classes would have to be ported to the other platforms - currently no CIM classes have been or are earmaked for porting as far as I'm aware - or the cmdlets would need to be rewritten to use the appropriate method of retrieving the data on each platform which is a non-trivial task
Advanced and ported Test-Connection cmdlet #5328
Resolve-DnsName can be easily implemented (with some seizures).
The remaining cmdlets are more difficult to implement because of the lack of standard APIs.
@iSazonov could you maybe share the Resolve-DnsName code?
Would be very helpful :)
@GrimSmiler I am not owner the cmdlet.. :-) MSFT is an owner. And the cmdlet is out of the repo.
I'd can re-create the cmdlet in the repo if we would get encouragement. Our policy requires the creation of an RFC. You could grab this if you want to get this cmdlet.
@iSazonov Then shall we create a feature request in https://github.com/dotnet/core or maybe https://github.com/dotnet/corefx about accessing such features?
@FranklinYu Seems it is out of CoreFX. CoreFX implements only base APIs. Interface management and route management is more high API level. Perhaps we could consider CIM. In any case, you need first do more research before make feature requests.
@iSazonov I'm not familiar with CIM, but I thought it's only available on Windows, isn't it?
@FranklinYu There is OMI project for portable implementation of CIM
https://cloudblogs.microsoft.com/windowsserver/2012/06/28/open-management-infrastructure/
IIUC if we implement those cmdlets in PowerShell with CIM, we need to include OMI in the package for non-Windows operating system, right?
OMI is another project and you can freely install OMI on non-Windows systems.
The current plan for the repo is the reverse — eliminate dependence on OMI native client library and implement WSMan client on managed code to get better compatibility for all platforms.
@SteveL-MSFT Could you please more clarify?
@iSazonov I’m having some issue looking up the documentation. Resolve-DnsName
only shows “Windows 8.1 and Windows Server 2012 R2” as latest version. Is it provided by a PowerShell package instead? Like NetworkingDsc?
No, it is a Windows component.
@iSazonov Then I don’t quite understand why it says that. When I select “Windows 10” in the Product list, it says
The requested page is not available for Windows 10 and Windows Server 2016 PowerShell. You have been redirected to the newest product version this page is available for.
So the Cmdlet works, but it is no longer documented? Is it deprecated?
Might be a documentation issue? I have Resolve-DnsName
on PS Core 6.1.0 with Windows 10.
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Resolve-DnsName 1.0.0.0 DnsClient
It looks as doc issue. You could report on the web page or PowerShell-Docs repo.
@vexx32 Resolve-DnsName
works in your PS Core? I installed PS Core 6.1.0 on my Windows 10 and Resolve-DnsName
is not found. It only works with the Windows PowerShell 5 that came with Windows 10.
Ah, yeah. I don't _think_ I changed my $env:PSModulePath, but I might have. It does _work_ but I'm not sure if PS Core searches in the WinPS module paths by default or if I added that into my environment variables directly at some point.
If you look C:\Windows\System32\WindowsPowerShell\v1.0\Modules\DnsClient\DnsClient.psd1
on Windows 10 1809 you will see CompatiblePSEditions = @('Desktop','Core')
. The latest Windows 10 version has many such updated modules compatible with PowerShell Core 6.1. This was announced in https://blogs.msdn.microsoft.com/powershell/2018/09/13/announcing-powershell-core-6-1/
@iSazonov I can confirm with Windows 10 1809. This is not available for Windows 10 1803 (which is still the majority). I'm wondering how do I write my own Cmdlet that are compatible with both Windows PowerShell and PowerShell Core, like DnsClient in this case?
@FranklinYu I recently wrote some docs on writing portable modules. It's not merged yet as it's still under review, but you can take a look at the PR for the content.
Regarding OMI above. My current recommendation is to not take a dependency on OMI.
Resolve-DnsName can be easily implemented (with some seizures).
I would like to help (because I myself need this Cmdlet). I did some research but there doesn't seem to be any built-in API (from .NET Core) to call, if we need record types like MX
or TXT
(required for the -Type
parameter); we either need to implement DNS protocol or to depend on third-party project.
It seems like the -Server
parameter is also missing from .NET Core API. I'm not familiar with meanings of other switches.
@FranklinYu .Net has TcpClient and UdpClient and we could easily implement any type request to DNS service. But it is better contribute to .Net CoreFX to enhance System.Net.NameResolution
APIs. Although if you want it can be done simultaneously.
Examples https://stackoverflow.com/questions/2669841/how-to-get-mx-records-for-a-dns-name-with-system-net-dns
I think this is related: dotnet/corefx#13890
I would try pushing that issue instead.
I think it would take long for CoreFX to pick them up. According to the CoreFX network team, they will be focusing on HTTP/3 once CoreFX 3.0 is released, so I guess it would be at least a year before they can put priority back to this DNS feature. Would it be possible to use community package DnsClient
before the function/feature lands on CoreFX?
@FranklinYu DnsClient is for .Net Framework.
@iSazonov It works in .NET Standard, according to NuGet. The package description is out of date; check the "Dependencies" section.
Where makes you think it's for .NET Framework only? I'll contact the author to fix it.
Looking at the DnsClient.NET repo, it appears to work with .Net Core 2.0 and even mentions Linux. However, this seems like a module that may be best created and supported by the community and shipped on PSGallery.
Is there any way to write a module to do "polyfill", that is to provide certain Cmdlet only if it is not available as built-in? Otherwise, the module won't install on new version of PowerShell with Resolve-DnsName
as built-in.
Typically, importing a module that contains a command that already exists will error, but you can -AlowClobber to force the import, and any conflicting commands are overridden with the new ones.
@vexx32 That’s exactly the thing I want to avoid.
-AllowClobber
will give user a very loud error message. This is what happened to Pscx (Pscx/Pscx#23) and I want to avoid it.module that may be best created and supported by the community and shipped on PSGallery.
MSFT has many useful modules which is not ported.
Perhaps the best option would be for the MSFT owners of the modules to make them open on GitHub and port them with community help. The new ported modules could replace current private modules in future.
@iSazonov Much easier said than done. Most of the Microsoft teams that own PowerShell modules are only doing closed source, so there's a big learning curve and work involved to make their code Open Source (legal review, private API usage, tests runnable by contributors outside of Microsoft environment, etc...). Also, making source code open is easy, but maintaining an active repo with the community takes resources that are likely not available. I suspect that many of the current teams that own a module have none of the original engineers that wrote that module and are only being maintained and not enhanced. There are some teams producing new PS modules and they may be more open to starting as Open Source, but we usually don't know about them until they're ready for release.
The best way to encourage a team to port or Open Source their module is to give them direct feedback through their feedback channel (which is probably UserVoice). You'll need to get others to support the cause if you want it to be prioritized higher or taken seriously. Teams do take customer feedback more critically than feedback from the PowerShell team.
@SteveL-MSFT Thanks for clarify!
to make their code Open Source
I guess it is unreal and haven't benefits. My suggestion is to start new projects to get ported modules.
MSFT as well as a community can get a lot of benefits from this as it will save everyone from rewriting common code. It will also save MSFT teams from unnecessary duplicate work. Your team could ask them that they would want to delegate, collect such commonly used functions, grab this in new project and get resources for new fin year.
I understand about UserVoice and customer feedback.
@SteveL-MSFT and others
Just jumping in here to clarify:
Looking at the DnsClient.NET repo, it appears to work with .Net Core 2.0 and even mentions Linux. However, this seems like a module that may be best created and supported by the community and shipped on PSGallery.
DnsClient.NET works totally fine cross platform on Linux etc.
The only problem a couple years ago was to resolve the System's DNS servers in case the user doesn't provide any.
The library has to query network interfaces to resolve those servers and older versions of .NET Core had no implementation of those methods in System.Net.NetworkInformation
for some targets, especially Linux and WPF.
But that should not be an issue anymore since .NET Core 2.2 I think.
I still have a native fallback in case the NetworkInformation doesn't yield any results...
All the other DNS protocol implementation simply uses UDP and/or TCP clients and sockets which are ported via .NET Core just fine.
The library is widely used by many customers in Linux containers within AKS for example in production for a long time now ;)
If there is anything I can help you with, like something is missing or blocking you using DnsClient, just ask or send a PR ;)
https://github.com/PowerShell/PowerShell/issues/12910 makes me think that, if a cross-platform Resolve-DnsName
is implemented, there should still be some way to run DNS queries via the native DNS resolver of Windows so that it can be used for diagnosing DNS problems that are affecting applications on Windows. An independent DNS client like DnsClient.NET cannot be expected to respect all Windows settings for things like DNS over HTTP or default suffixes.
Possibilities:
Resolve-DnsName -UseNativeResolver
, using DnsQueryEx on Windows. On GNU/Linux, the GNU C Library does not appear to provide functions for getting an entire DNS response; no doubt there are such functions in other libraries, but perhaps none of them is so widely used by applications that it would be worth supporting for this diagnostic purpose.Test-Connection
or [System.Net.Dns]::GetHostEntry
for this diagnostic. This assumes that .NET will keep using the DNS resolver of the operating system, like https://github.com/dotnet/runtime/issues/19443#issuecomment-264531083 recommends.Is there a reason a Resolve-DnsName cmdlet can't simply use the System.Net.Dns
API for this functionality?
System.Net.Dns
does not currently provide all the information that Resolve-DnsName
outputs. On Windows PowerShell 5.1:
PS C:\> Resolve-DnsName www.microsoft.com
Name Type TTL Section NameHost
---- ---- --- ------- --------
www.microsoft.com CNAME 365 Answer www.microsoft.com-c-3.edgekey.net
www.microsoft.com-c-3.edgekey. CNAME 365 Answer www.microsoft.com-c-3.edgekey.net.globalredir.akadns.net
net
www.microsoft.com-c-3.edgekey. CNAME 365 Answer e13678.dspb.akamaiedge.net
net.globalredir.akadns.net
Name : e13678.dspb.akamaiedge.net
QueryType : AAAA
TTL : 15
Section : Answer
IP6Address : 2a02:26f0:41:692::356e
Name : e13678.dspb.akamaiedge.net
QueryType : AAAA
TTL : 15
Section : Answer
IP6Address : 2a02:26f0:41:68e::356e
Name : e13678.dspb.akamaiedge.net
QueryType : AAAA
TTL : 15
Section : Answer
IP6Address : 2a02:26f0:41:695::356e
Name : e13678.dspb.akamaiedge.net
QueryType : AAAA
TTL : 15
Section : Answer
IP6Address : 2a02:26f0:41:68f::356e
Name : e13678.dspb.akamaiedge.net
QueryType : AAAA
TTL : 15
Section : Answer
IP6Address : 2a02:26f0:41:694::356e
Name : e13678.dspb.akamaiedge.net
QueryType : A
TTL : 24
Section : Answer
IP4Address : 23.37.97.67
On PowerShell 7.1.0-preview.3:
PS C:\> [System.Net.Dns]::GetHostEntry("www.microsoft.com")
HostName Aliases AddressList
-------- ------- -----------
e13678.dspb.akamaiedge.net {} {2a02:26f0:41:691::356e, 2a02:26f0:41:685::356e, 2a02:26f0:41:68a::356e, 2a02:26f0:…
So the CNAME chain and TTL values are not available.
Also, the methods of System.Net.Dns
only take IPAddress address
or string hostNameOrAddress
as a parameter, so there is no way to implement most of the parameters of Resolve-DnsName
, such as -Type
or -Server
. If a native-resolver mode using System.Net.Dns
were part of Resolve-DnsName
, it might be best implemented as a separate parameter set.
Most helpful comment
@FranklinYu I recently wrote some docs on writing portable modules. It's not merged yet as it's still under review, but you can take a look at the PR for the content.
Regarding OMI above. My current recommendation is to not take a dependency on OMI.