-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please add documentation for PowerShell developers #161
Comments
The api you use through powershell is just the standard api and the documentation for other .net langauges will apply equally. It may not have the specific powershell syntax but just like finding a vb.net sample when you're using c# you should be able to translate it. The problem you're having is that you're trying to use the netstandard assembly and that won't work because netstandard isn't a platform. You need to use the correct binary for the runtime you're on, so netfx or netcore. I'm also not sure how you're going to deal with the dependency chain. |
Although this would be good to have, I agree on that, but currently we are occupied with lot of high priority work including .NET API Browser Documentation onboarding for M.D.S. Once we get some bandwidth, we will consider adding this for Powershell users. |
I also was unable to use this package with PowerShell — specifically, in a PowerShell binary module. This package worked with PowerShell 5.1 (targeting The throw new PlatformNotSupportedException(System.SR.PlatformNotSupported_DataSqlClient); The same DLL in my The relevant parts of my csproj: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<!-- This causes all DLLs from NuGet dependencies to be copied to the output folder. -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19249.1" />
</ItemGroup>
</Project> For now I'm just going back to |
When targeting netcore and picking your DLL manually, you need to pick the appropriate one from the runtime folder. The DLL in the lib folder just throws the PlatformNotSupported exception everywhere. The reason for this boils down to cross-platform support. SqlClient needs different DLLs depending on whether (at runtime) the environment is Windows versus Linux. But as Wraith2 mentioned, you are also going to have a problem with the dependency chain. |
I was able to get M.D.S working in my case via @David-Engel 's advice. It was quite painful, though. I had to traverse the M.D.S dependency graph, loading each DLL into ILSpy to see which references were unresolved, adding .csproj elements to resolve them, and recursing until all DLLs in the graph could resolve their dependencies. This was made more difficult by dependencies' assembly versions and nupkg versions often not matching, and by the dependency nupkgs rarely having release notes to explain what their versions mean. Then I needed a .ps1 script to load the appropriate M.D.S DLL constellation at module load time. I'm not confident that my solution is a correct one, and I'm not looking forward to doing this work again when M.D.S updates. The desired developer experience here, IMO, is to have a simple set of instructions to follow (e.g. "go add this NuGet package"), resulting in a small .csproj that just works when you hit F5. I'm not an expert in the intricacies of packaging for various target frameworks/platforms/runtimes, nor should I need to be. That stuff should be handled automatically by the tooling. MyProject.csproj<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19249.1" />
</ItemGroup>
<ItemGroup>
<None Update="*.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<!-- Microsoft.Data.SqlClient.dll -->
<None Include="$(NuGetPackageRoot)microsoft.data.sqlclient\1.0.19249.1\lib\net46\Microsoft.Data.SqlClient.dll">
<Link>deps\win-net461\Microsoft.Data.SqlClient.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)microsoft.data.sqlclient\1.0.19249.1\runtimes\win\lib\netcoreapp2.1\Microsoft.Data.SqlClient.dll">
<Link>deps\win-netcoreapp2.1\Microsoft.Data.SqlClient.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)microsoft.data.sqlclient\1.0.19249.1\runtimes\unix\lib\netcoreapp2.1\Microsoft.Data.SqlClient.dll">
<Link>deps\unix-netcoreapp2.1\Microsoft.Data.SqlClient.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- SNI.dll -->
<None Include="$(NuGetPackageRoot)microsoft.data.sqlclient.sni\1.0.19235.1\buildTransitive\net46\x64\SNI.dll">
<Link>deps\win-net461\x64\SNI.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)microsoft.data.sqlclient.sni\1.0.19235.1\buildTransitive\net46\x86\SNI.dll">
<Link>deps\win-net461\x86\SNI.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)runtime.win7-x64.runtime.native.system.data.sqlclient.sni\4.3.0\runtimes\win7-x64\native\sni.dll">
<Link>deps\win-netcoreapp2.1\x64\sni.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)runtime.win7-x86.runtime.native.system.data.sqlclient.sni\4.3.0\runtimes\win7-x86\native\sni.dll">
<Link>deps\win-netcoreapp2.1\x86\sni.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- Microsoft.Identity.Client.dll -->
<None Include="$(NuGetPackageRoot)microsoft.identity.client\3.0.8\lib\net45\Microsoft.Identity.Client.dll">
<Link>deps\win-net461\Microsoft.Identity.Client.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)microsoft.identity.client\3.0.8\lib\netcoreapp2.1\Microsoft.Identity.Client.dll">
<Link>deps\win-netcoreapp2.1\Microsoft.Identity.Client.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)microsoft.identity.client\3.0.8\lib\netcoreapp2.1\Microsoft.Identity.Client.dll">
<Link>deps\unix-netcoreapp2.1\Microsoft.Identity.Client.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- System.Configuration.ConfigurationManager.dll -->
<None Include="$(NuGetPackageRoot)system.configuration.configurationmanager\4.5.0\lib\netstandard2.0\System.Configuration.ConfigurationManager.dll">
<Link>deps\win-netcoreapp2.1\System.Configuration.ConfigurationManager.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(NuGetPackageRoot)system.configuration.configurationmanager\4.5.0\lib\netstandard2.0\System.Configuration.ConfigurationManager.dll">
<Link>deps\unix-netcoreapp2.1\System.Configuration.ConfigurationManager.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- System.Security.Permissions.dll -->
<None Include="$(_NugetFallbackFolder)\system.security.permissions\4.5.0\lib\netstandard2.0\System.Security.Permissions.dll">
<Link>deps\win-netcoreapp2.1\System.Security.Permissions.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- System.Text.Encoding.CodePages.dll -->
<None Include="$(_NugetFallbackFolder)\system.text.encoding.codepages\4.5.0\lib\netstandard2.0\System.Text.Encoding.CodePages.dll">
<Link>deps\win-netcoreapp2.1\System.Text.Encoding.CodePages.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(_NugetFallbackFolder)\system.text.encoding.codepages\4.5.0\lib\netstandard2.0\System.Text.Encoding.CodePages.dll">
<Link>deps\unix-netcoreapp2.1\System.Text.Encoding.CodePages.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> Resolve-SqlClient.ps1if ($PSEdition -eq 'Desktop')
{
# PowerShell 5.1 on Windows
Add-Type -Path (Join-Path $PSScriptRoot deps\win-net461\Microsoft.Data.SqlClient.dll)
}
elseif ($IsWindows)
{
# PowerShell 6.x+ on Windows
Add-Type -Path (Join-Path $PSScriptRoot deps\win-netcoreapp2.1\Microsoft.Data.SqlClient.dll)
}
else
{
# PowerShell 6.x+ on *nix
Add-Type -Path (Join-Path $PSScriptRoot deps\unix-netcoreapp2.1\Microsoft.Data.SqlClient.dll)
} |
could someone just give us PowerShell guys that are used to use just PowerShell Gallery modules clear step by step working connection example using Microsoft.Data.Sqlclient? I am having .NET 4.6 and I was able to add nuget as package provider to PowerShell, I was able to Install-Package Microsoft.Data.Sqlclient with PowerShell. But when I would like to create object in PowerShell code I need to load custom dll. When using Add-Type it is giving me errors with dependencies. However I can see all these additional required in same packages folder. When I was trying to load them one by one before calling Microsoft.Data.Sqlclient I was able to do it with Add-Type for Microsoft.Identity.Client and System.Data.Common, but no luck with Microsoft.Data.SqlClient.sni (missing manifest error). Can someone pls provide step by step PowerShell guide how can I use this new Microsoft.Data.Sqlclient namespace? I can do it pretty easily with System.Data.SqlClient but I'd really love to use new namespace now. |
Keep in mind that the developers of SqlClient are not PowerShell experts/developers. After a bit of searching, it sounds like the PowerShell infrastructure might just not quite be up to easily handling NuGet packages yet. I found Loading Assemblies from NuGet Packages and Make using NuGet packages installed with Install-Package easier to use - make Add-Type support NuGet packages It might be better to ask in the PowerShell repository how to correctly load and use a Nuget package. It was much easier to use System.Data.SqlClient in .NET Framework because it and all dependencies were already installed for you and it only had to support one platform, Windows. |
hi @David-Engel , I can load with Add-Type any nuget package without any problem if package has no dependency, Problem is not just loading nuget packages into PowerShell, it can be done, problem is loading nuget packages with all dependencies into PowerShell. And all dependencies should have manifests, etc. When I want to abstract this problem is: |
You just described the problem with PowerShell. Dependencies are an integral part of NuGet packages. Once you leave .NET Framework, which was a very monolithic install of a lot of core dependencies, it's a rare package that has zero dependencies. Until PowerShell fully supports NuGet packages, what new features are you blocked from using in Microsoft.Data.SqlClient that are not available in System.Data.SqlClient on .NET Framework? |
@David-Engel thank you for your feedback, I am new to GitHub, can you tell me where we need to push so "Powershell fully supports NuGet packages" ? |
I assume the PowerShell repository. Specifically, the issue I mentioned above looks relevant: Make using NuGet packages installed with Install-Package easier to use - make Add-Type support NuGet packages |
Thank you all for your patience with me and guidance, I finally get it done. Key was to switch to PowerShell Core. I will test my scenario on fresh VM next week and let you know step by step if you are interested in. Have a great weekend all |
I've documented it here |
I also played around with package dependencies, looks brutal, I hope I have it wrong , check it here |
Ok, I reworked dependency tree for package from post above. I was using Get-Package command which is not able to filter dependencies by target platform (I've opened issue for PowerShell here) . Alternatively I used Nuget API to determine full dependency tree for current major builds and .NET core 2.1 |
Awesome work, @MartinHBA ! thank you so much |
@potatoqualitee , after more research on this topic here is conclusion:
Current situation is:
Whole nuget thing with packages with dependencies can be easily used from Visual Studio with C# project where you simply put nuget package to your project and it's automatically loaded with dependencies for your project. Edit: I've also updated my gist article to compare work with this nuget package in .NET console (piece of cake) |
Closing issue due to existing limitations in NuGet with PowerShell. |
@SteveL-MSFT - please see #161 (comment) - is there an appropriate repo that we can report this to correct? |
@potatoqualitee in the new PSGetv3 spec, we have a section to help PowerShell users use arbitrary nuget packages with intent to understand runtime ids appropriate for your system. I believe this should help resolve some of these issues. |
@SteveL-MSFT NuGet and PowerShellGet are separate package providers: Get-PackageProvider do I understand you correctly that new PowerShellGet will allow installation of NuGet Packages? |
Intent is to have PSGetv3 replace the need for PackageManagement with regards to installing arbitrary NuGet pkgs |
Thank you, Steve! |
@SteveL-MSFT can you pls share url to follow for PSgetv3 updates? |
@potatoqualitee easiest way forward is: edit: it worked before, now again showing dependency loop |
Does not work for me.
If this is the replacement for such a basic package as System.Data.SqlClient, why is it so difficult to use with PowerShell? So far, the only thing I've found to work is a hack at best. |
@sharpjs , can you pls paste here your $psversiontable? |
I'll try changing my package source to the
|
FWIW, the hack I currently use for PowerShell binary modules is: In project file: <Project Sdk="Microsoft.NET.Sdk">
...other stuff...
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RuntimeIdentifiers>win-arm;win-arm64;win-x64;win-x86;unix</RuntimeIdentifiers>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.0.0" />
<PackageReference Include="System.Management.Automation" Version="7.0.3">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
...other stuff...
</Project> In a if ($IsWindows)
{
Add-Type -Path (Join-Path $PSScriptRoot runtimes\win\lib\netcoreapp3.1\Microsoft.Data.SqlClient.dll)
}
else
{
Add-Type -Path (Join-Path $PSScriptRoot runtimes\unix\lib\netcoreapp3.1\Microsoft.Data.SqlClient.dll)
} And using System.IO;
using System.Runtime.InteropServices;
namespace SomeModule
{
// Microsoft.Data.SqlClient 2.0.0 and later, at least when used within this
// PowerShell module, has trouble locating the appropriate SNI DLL. The
// workaround is to load it manually.
internal static class SniLoader
{
internal static void Load()
{
// Does platform need SNI?
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return; // no
// Get runtime identifier
var rid = RuntimeInformation.ProcessArchitecture switch
{
Architecture.X86 => "win-x86",
Architecture.X64 => "win-x64",
Architecture.Arm => "win-arm",
Architecture.Arm64 => "win-arm64",
_ => null
};
// Does runtime need SNI?
if (rid == null)
return; // no
// Get path to SNI DLL
var sniDllPath = Path.Combine(
Path.GetDirectoryName(typeof(SniLoader).Assembly.Location),
"runtimes",
rid,
"native",
"Microsoft.Data.SqlClient.SNI.dll"
);
// Load SNI DLL
NativeLibrary.Load(sniDllPath);
}
}
} ...and make sure you execute |
Sounds like whats really needed is a better powershell module that wraps sqlclient. Invoke-sqlcmd isn't it. |
@simonsabin I'm working on it. |
@sharpjs @cheenamalhotra @potatoqualitee @simonsabin
and now seeing PowerShellGet v3 commands suite: Then I tried and I've got some result
So I've tried final promising command:
However it's stuck for me as below: If you would have more luck with this approach please let me know, I found similar issue opened for this. |
Could you try making an entry for NuGet as trusted source? Wondering if this is related: https://github.com/PowerShell/PowerShellGet/issues/154#issuecomment-647027689 ? |
@cheenamalhotra it worked fine to install Pester (without "force" parameter, that is unavailable), trying same for Microsoft.Data.SqlClient it didn't work and is stuck forever Nuget is trusted for me |
Should it not be: https://api.nuget.org/v3/index.json ? |
@ErikEJ Pester installation from Nuget works, would you kindly test this from your side? I tested all http and https and v2 and v3, no luck for Microsoft.Data.SqlClient, works smoothly for Pester package. |
Is there any other .NET NuGet package that worked for you? |
well, is there? who knows... |
I can't get it work at current, I just wait for next Powershell 7 preview version
|
Is your feature request related to a problem? Please describe.
I am a PowerShell developer and do not know how to use this SQL Client. I cannot find any docs that help.
Describe the solution you'd like
Add-Type -Path
that at least includes a query to a remote server.# Pre-SQL Server 2008
or# For Azure
I would like PowerShell to be given as much love as C# in the official docs. Our community uses the heck out of SqlClient.
Describe alternatives you've considered
I tried it myself to no avail.
I also tried in Core with the same error
Additional context
Please also keep PowerShell documentation in mind for other new, cool SQL-related projects, not just cmdlets that are made (which are great for end-users), but the actual classes (which are appropriate for PS Devs).
The text was updated successfully, but these errors were encountered: