├── test ├── automation │ ├── .gitignore │ ├── automationcase.ps1 │ ├── SHiPSTest │ │ ├── SHiPSTest.psd1 │ │ └── SHiPSTest.psm1 │ ├── abc.psm1 │ ├── sampleRecursion.psm1 │ └── ctor.psm1 ├── adhoc │ └── adhoc1.psm1 ├── Azure.Network │ ├── Azure.Network.psm1 │ └── Azure.Network.psd1 └── Azure.Compute │ ├── Azure.Compute.psm1 │ └── Azure.Compute.psd1 ├── docs ├── images │ └── pie.png ├── README.md └── PublicAPIsAndMore.md ├── src ├── signing │ └── 35MSSharedLib1024.snk ├── p2f │ ├── src │ │ ├── Samples │ │ │ ├── P2F_Sample1_NullProvider │ │ │ │ ├── packages.config │ │ │ │ ├── Items │ │ │ │ │ └── NullItem.cs │ │ │ │ ├── NullDrive.cs │ │ │ │ ├── Paths │ │ │ │ │ ├── NullPathResolver.cs │ │ │ │ │ └── NullRootPathNode.cs │ │ │ │ ├── NullProvider.cs │ │ │ │ ├── Properties │ │ │ │ │ └── AssemblyInfo.cs │ │ │ │ └── P2F_Sample1_NullProvider.csproj │ │ │ ├── P2F_Sample2_TypeProvider │ │ │ │ ├── packages.config │ │ │ │ ├── Properties │ │ │ │ │ └── AssemblyInfo.cs │ │ │ │ ├── TypeProvider.cs │ │ │ │ └── P2F_Sample2_TypeProvider.csproj │ │ │ └── P2F_Sample3_TypeProvider │ │ │ │ ├── packages.config │ │ │ │ ├── Properties │ │ │ │ └── AssemblyInfo.cs │ │ │ │ ├── TypeProvider.cs │ │ │ │ ├── TypePathNode.cs │ │ │ │ └── P2F_Sample3_TypeProvider.csproj │ │ ├── CodeOwls.PowerShell │ │ │ ├── CodeOwls.PowerShell.Paths │ │ │ │ ├── IClearItemContent.cs │ │ │ │ ├── nuget.config │ │ │ │ ├── IMoveItem.cs │ │ │ │ ├── ISetItemContent.cs │ │ │ │ ├── IGetItemContent.cs │ │ │ │ ├── CodeOwls.PowerShell.Paths.csproj │ │ │ │ ├── IPathValue.cs │ │ │ │ ├── IClearItem.cs │ │ │ │ ├── ISetItem.cs │ │ │ │ ├── IRemoveItem.cs │ │ │ │ ├── IRenameItem.cs │ │ │ │ ├── IInvokeItem.cs │ │ │ │ ├── ICopyItem.cs │ │ │ │ ├── Processors │ │ │ │ │ ├── IPathResolver.cs │ │ │ │ │ ├── PathResolverDecorator.cs │ │ │ │ │ ├── PathResolverBase.cs │ │ │ │ │ ├── PSProviderPathResolver.cs │ │ │ │ │ └── IProviderContext.cs │ │ │ │ ├── INewItem.cs │ │ │ │ ├── Attributes │ │ │ │ │ └── CmdletHelpPathIDAttribute.cs │ │ │ │ ├── IPathNode.cs │ │ │ │ ├── Extensions │ │ │ │ │ └── PathStringExtensions.cs │ │ │ │ ├── Exceptions │ │ │ │ │ ├── NodeDoesNotSupportCmdletException.cs │ │ │ │ │ ├── CopyOrMoveToExistingItemException.cs │ │ │ │ │ ├── CopyOrMoveToNonexistentContainerException.cs │ │ │ │ │ ├── CopyOrMoveItemInternalException.cs │ │ │ │ │ ├── ProviderException.cs │ │ │ │ │ ├── CopyOrMoveToDifferentContainerTypeException.cs │ │ │ │ │ └── MamlHelpDocumentExistsButCannotBeLoadedException.cs │ │ │ │ ├── PathValue.cs │ │ │ │ └── PathNodeBase.cs │ │ │ └── CodeOwls.PowerShell.Provider │ │ │ │ ├── CollectionExtensions.cs │ │ │ │ ├── CodeOwls.PowerShell.Provider.csproj │ │ │ │ ├── NullDisposable.cs │ │ │ │ └── Drive.cs │ │ ├── Nuget │ │ │ └── p2f.nuspec │ │ ├── CodeOwls.AssemblyInfo.cs │ │ └── CodeOwls.PowerShell.AssemblyInfo.cs │ ├── README.md │ └── LICENSE.md ├── Microsoft.PowerShell.SHiPS │ ├── SHiPSParameters.cs │ ├── Node │ │ ├── SHiPSLeaf.cs │ │ ├── PathNodeInfo.cs │ │ ├── ProviderContext.cs │ │ ├── PSObjectNodeService.cs │ │ ├── SHiPSDirectory.cs │ │ ├── ContentHelper.cs │ │ ├── LeafNodeService.cs │ │ └── SHiPSBase.cs │ ├── SHiPSAttributeHandler.cs │ ├── SHiPSProviderAttribute.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Microsoft.PowerShell.SHiPS.csproj │ ├── Utility │ │ └── ProgressTracker.cs │ └── SHiPSConstants.cs └── Modules │ ├── SHiPS.psd1 │ └── SHiPS.formats.ps1xml ├── samples ├── AzurePSDrive │ └── README.md ├── CimPSDrive │ └── README.md ├── FamilyTreeInCSharp │ ├── packages.config │ ├── FamilyTreeInCSharp.psd1 │ ├── FamilyTreeInCSharp.sln │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── FamilyTreeInCSharp.cs │ └── FamilyTreeInCSharp.csproj ├── FileSystem │ ├── README.md │ └── FileSystem.psm1 ├── ShowProgress │ ├── README.md │ └── ShowProgress.psm1 ├── Library │ ├── README.md │ └── Library.psm1 ├── FamilyTree │ ├── README.md │ └── FamilyTree.psm1 └── DynamicParameter │ └── README.md ├── tools ├── travis.sh └── download.sh ├── .gitignore ├── .github └── ISSUE_TEMPLATE.md ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.txt ├── appveyor.yml ├── ThirdPartyNotices.txt └── vs2015 └── SHiPS.sln /test/automation/.gitignore: -------------------------------------------------------------------------------- 1 | # Auto generated test fixture 2 | Library.psm1 3 | -------------------------------------------------------------------------------- /docs/images/pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerShell/SHiPS/HEAD/docs/images/pie.png -------------------------------------------------------------------------------- /src/signing/35MSSharedLib1024.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerShell/SHiPS/HEAD/src/signing/35MSSharedLib1024.snk -------------------------------------------------------------------------------- /test/automation/automationcase.ps1: -------------------------------------------------------------------------------- 1 | new-psdrive -name kk -psprovider SHiPS -root Test#Root 2 | cd kk: 3 | dir 4 | get-module -ListAvailable -------------------------------------------------------------------------------- /samples/AzurePSDrive/README.md: -------------------------------------------------------------------------------- 1 | [AzurePSDrive][AzurePSDrive] - Navigate Azure Resources Just Like a File System 2 | 3 | [AzurePSDrive]: https://github.com/PowerShell/AzurePSDrive 4 | -------------------------------------------------------------------------------- /samples/CimPSDrive/README.md: -------------------------------------------------------------------------------- 1 | [CimPSDrive][CimPSDrive] - Navigate CIM Classes and Namespaces Just Like a File System 2 | 3 | [CimPSDrive]: https://github.com/PowerShell/CimPSDrive 4 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample2_TypeProvider/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample3_TypeProvider/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tools/travis.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | ulimit -n 4096 3 | 4 | echo "TRAVIS_EVENT_TYPE value $TRAVIS_EVENT_TYPE" 5 | 6 | 7 | git submodule update --init 8 | 9 | 10 | pwsh -c "cd src; ./bootstrap.ps1; ./build.ps1 -framework "netstandard2.0" Release" 11 | 12 | sudo pwsh -c "Import-Module ./tools/setup.psm1; Invoke-SHiPSTest" 13 | -------------------------------------------------------------------------------- /src/p2f/README.md: -------------------------------------------------------------------------------- 1 | # P2F 2 | 3 | The PowerShell Provider Framework (P2F) performs the heavy lifting for developing PowerShell Providers. 4 | 5 | # Cross-Platform, and Cross-PowerShell 6 | 7 | The P2F Framework now targets .NET Standard 2.0 and uses the PowerShellStandard.Library to support building providers that are cross-platform and work on PowerShell (3, 4), 5 and 6 ... 8 | -------------------------------------------------------------------------------- /test/automation/SHiPSTest/SHiPSTest.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | RootModule= 'SHiPSTest.psm1' 3 | ModuleVersion = '1.0.0' 4 | GUID = 'A5FE6B04-385F-470F-9347-66EB3645B466' 5 | Author = 'Microsoft Corporation' 6 | CompanyName = 'Microsoft Corporation' 7 | Copyright = '© Microsoft Corporation. All rights reserved.' 8 | Description = 'SHiPS Test' 9 | PowerShellVersion = '5.0' 10 | } 11 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IClearItemContent.cs: -------------------------------------------------------------------------------- 1 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 2 | 3 | namespace CodeOwls.PowerShell.Paths 4 | { 5 | public interface IClearItemContent 6 | { 7 | void ClearContent(IProviderContext providerContext); 8 | object ClearContentDynamicParameters(IProviderContext providerContext); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/Items/NullItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ProviderFramework_1_TheNullProvider 7 | { 8 | public class NullItem 9 | { 10 | public override string ToString() 11 | { 12 | return "This is a null item."; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/FamilyTreeInCSharp.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | RootModule= 'FamilyTreeInCSharp.dll' 3 | ModuleVersion = '1.0.0' 4 | GUID = 'A5FE6B04-385F-470F-9347-66EB3645B433' 5 | Author = 'Microsoft Corporation' 6 | CompanyName = 'Microsoft Corporation' 7 | Copyright = '© Microsoft Corporation. All rights reserved.' 8 | Description = 'SHiPS Samples' 9 | PowerShellVersion = '5.0' 10 | } 11 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IMoveItem.cs: -------------------------------------------------------------------------------- 1 | 2 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 3 | 4 | namespace CodeOwls.PowerShell.Provider.PathNodes 5 | { 6 | public interface IMoveItem 7 | { 8 | object MoveItemParameters { get; } 9 | 10 | IPathValue MoveItem(IProviderContext providerContext, string path, string movePath, IPathValue destinationContainer); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/ISetItemContent.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation.Provider; 2 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 3 | 4 | namespace CodeOwls.PowerShell.Paths 5 | { 6 | public interface ISetItemContent 7 | { 8 | IContentWriter GetContentWriter(IProviderContext providerContext); 9 | object GetContentWriterDynamicParameters(IProviderContext providerContext); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/NullDrive.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | 3 | namespace ProviderFramework_1_TheNullProvider 4 | { 5 | /// 6 | /// the drive class 7 | /// 8 | /// used by the NullProvider class to define the default drive 9 | /// for the provider 10 | /// 11 | public class NullDrive : CodeOwls.PowerShell.Provider.Drive 12 | { 13 | public NullDrive(PSDriveInfo driveInfo) : base(driveInfo) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/SHiPSParameters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Microsoft.PowerShell.SHiPS 4 | { 5 | /// 6 | /// These are PSBoundParameters to be used while PowerShell.Invoke(). 7 | /// 8 | internal class SHiPSParameters 9 | { 10 | internal bool Force { get; set; } 11 | internal bool Verbose { get; set; } 12 | internal bool Debug { get; set; } 13 | 14 | internal Dictionary BoundParameters { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IGetItemContent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Management.Automation.Provider; 5 | using System.Text; 6 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 7 | 8 | namespace CodeOwls.PowerShell.Paths 9 | { 10 | public interface IGetItemContent 11 | { 12 | IContentReader GetContentReader(IProviderContext providerContext); 13 | object GetContentReaderDynamicParameters(IProviderContext providerContext); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/SHiPSLeaf.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.PowerShell.SHiPS 2 | { 3 | 4 | /// 5 | /// Defines a type that represents a leaf node. 6 | /// 7 | public class SHiPSLeaf : SHiPSBase 8 | { 9 | /// 10 | /// Default C'tor. 11 | /// 12 | public SHiPSLeaf() 13 | { 14 | } 15 | 16 | /// 17 | /// C'tor. 18 | /// 19 | /// Name of the node. 20 | public SHiPSLeaf(string name) : base(name, isLeaf:true) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/Paths/NullPathResolver.cs: -------------------------------------------------------------------------------- 1 | using CodeOwls.PowerShell.Paths.Processors; 2 | using CodeOwls.PowerShell.Provider.PathNodes; 3 | 4 | namespace ProviderFramework_1_TheNullProvider 5 | { 6 | /// 7 | /// the path node processor 8 | /// 9 | class NullPathResolver : PathResolverBase 10 | { 11 | /// 12 | /// returns the first node factory object in the path graph 13 | /// 14 | protected override IPathNode Root 15 | { 16 | get 17 | { 18 | return new NullRootPathNode(); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### 2 | SHiPS Specific 3 | ### 4 | 5 | # Build results 6 | [Dd]ebug/ 7 | [Dd]ebugPublic/ 8 | [Rr]elease/ 9 | [Rr]eleases/ 10 | x64/ 11 | x86/ 12 | bld/ 13 | [Bb]in/ 14 | [Oo]bj/ 15 | [Ll]og/ 16 | out/ 17 | 18 | # Visual Studio 2015 cache/options directory 19 | .vs/ 20 | 21 | # MSTest test Results 22 | [Tt]est[Rr]esult*/ 23 | [Bb]uild[Ll]og.* 24 | 25 | # NUNIT 26 | *.VisualState.xml 27 | test/*[Tt]est[Rr]esults.xml 28 | test/automation/*[Tt]est[Rr]esults.xml 29 | test/TestDir 30 | test/TestFile* 31 | 32 | # .NET Core 33 | project.lock.json 34 | project.fragment.lock.json 35 | artifacts/ 36 | **/Properties/launchSettings.json 37 | 38 | # Auto generated 39 | tools/install-powershell.ps1 40 | packages/ -------------------------------------------------------------------------------- /src/p2f/src/Nuget/p2f.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | P2F 5 | $id$ 6 | Code Owls LLC 7 | Code Owls LLC 8 | https://github.com/beefarino/p2f/blob/master/LICENSE.md 9 | https://github.com/beefarino/p2f 10 | https://avatars1.githubusercontent.com/u/325790?s=140 11 | true 12 | Framework for implementing PowerShell Providers. 13 | 16 | Copyright (c) 2014 Code Owls LLC, All Rights Reserved 17 | PowerShell Providers 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/PathNodeInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CodeOwls.PowerShell.Provider.PathNodes; 3 | 4 | namespace Microsoft.PowerShell.SHiPS 5 | { 6 | /// 7 | /// A class containing the current node information. 8 | /// 9 | internal class PathNodeInfo 10 | { 11 | internal string Path { get; set; } 12 | internal string PathWithNoEndSlash { get; set; } 13 | internal IPathNode NodeObject { get; set; } 14 | internal List Children { get; set; } 15 | 16 | internal void Set(string path, IPathNode node, List children) 17 | { 18 | Path = path; 19 | PathWithNoEndSlash = path?.TrimEnd('/', '\\'); 20 | NodeObject = node; 21 | Children = children; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/FileSystem/README.md: -------------------------------------------------------------------------------- 1 | # Sample Provider - Modeling Windows File System 2 | 3 | ## Step 1- Install SHiPS 4 | 5 | Follow the instructions [in here][readme] to download and install the SHiPS. 6 | 7 | ## Step 2 - Review the sample code 8 | 9 | See the [FileSystem module][fs]. 10 | 11 | ## Step 3 - Try it out 12 | 13 | ```powershell 14 | Import-Module SHiPS 15 | Import-Module .\samples\FileSystem 16 | New-PSDrive -Name FS -PSProvider SHiPS -Root FileSystem#Home 17 | cd FS: 18 | dir 19 | ``` 20 | 21 | ## Key takeaways from this example 22 | 23 | - Unlike the [FamilyTree][ft], a tree structure, the FileSystem follows a recursion model from root to leaf. 24 | - We used a data field, `Hidden [object]$data` to pass down the context from parent node to child. 25 | 26 | [readme]: ../../README.md#Installing-SHiPS 27 | [fs]: FileSystem.psm1 28 | [ft]: ../FamilyTree 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | Steps to reproduce 12 | ------------------ 13 | 14 | 15 | Expected behavior 16 | ----------------- 17 | 18 | 19 | Actual behavior 20 | --------------- 21 | 22 | 23 | Environment data 24 | ---------------- 25 | 26 | 27 | 28 | ```powershell 29 | $PSVersionTable 30 | Get-Module SHiPS 31 | ``` 32 | 33 | 34 | 35 | ```powershell 36 | $env:ACC_VERSION 37 | $env:ACC_LOCATION 38 | Get-Module SHiPS 39 | Get-Module AzurePSDrive 40 | ``` 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: cpp 3 | 4 | git: 5 | depth: 1000 6 | 7 | os: 8 | - linux 9 | - osx 10 | sudo: required 11 | dist: trusty 12 | osx_image: xcode8.1 13 | 14 | matrix: 15 | allow_failures: 16 | - os: osx 17 | fast_finish: true 18 | 19 | 20 | addons: 21 | artifacts: 22 | paths: $(ls ./../SHiPS.coreclr.zip | tr "\n" ":") 23 | 24 | install: 25 | - export PATH=~/.dotnet:$PATH 26 | # Default 2.0.0 Ruby is buggy 27 | # Default bundler version is buggy 28 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 29 | rvm install ruby-2.3.3; 30 | rvm --default use 2.3.3; 31 | fi 32 | - bash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) 33 | - pushd tools 34 | - chmod +x travis.sh 35 | - popd 36 | 37 | script: 38 | - echo "TRAVIS_EVENT_TYPE value $TRAVIS_EVENT_TYPE" 39 | - ./tools/travis.sh 40 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | CHANGELOG 2 | ======== 3 | ## 0.8.1 4 | * Added Get-Content and Set-Content. 5 | ## 0.8.0 6 | * Switched to using .NET Standard 2.0 & PowerShellStandard.Library to allow a single cross-platform binary 7 | - It requires .NET 4.7.1 running on Windows PowerShell 8 | 9 | ## 0.7.5 10 | * Added error handling for unsupported provider cmdlets. 11 | ## 0.7.2 12 | * Bug fixes for 'dir -force' case. 13 | ## 0.7.1 14 | * Perf improvement. For providers using cached data, [SHiPSProvider(UseCache=$true)], 'dir -force' will only refresh the last node in the path. 15 | * Allowed to navigate home directory, e.g., 'dir ~' or 'cd ~' under SHiPS based provider drive. 16 | ## 0.7.0 17 | * Fixed forward slash issue on Linux. 18 | * Fixed Set-Location drive: path issue on Linux. 19 | ## 0.6.0 20 | * Fixed Test-Path cmdlet. 21 | * Updated SHiPS to build with .NET Core 2.0.5 to be in sync with pwsh. 22 | * Fixed SHiPS formats.ps1xml. 23 | ## 0.3.0 24 | * Big Bang 25 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/SHiPSAttributeHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Microsoft.PowerShell.SHiPS 5 | { 6 | /// 7 | /// A helper class for getting SHiPSPropertyAttribute settings. 8 | /// 9 | internal class SHiPSAttributeHandler 10 | { 11 | private static SHiPSProviderAttribute defaultAttribute = new SHiPSProviderAttribute(); 12 | 13 | internal static SHiPSProviderAttribute GetSHiPSProperty(Type type) 14 | { 15 | var descriptions = (SHiPSProviderAttribute[])type.GetTypeInfo().GetCustomAttributes(typeof(SHiPSProviderAttribute), inherit:true); 16 | 17 | if (descriptions.Length == 0) 18 | { 19 | // if a module does not specify any attributes, we use the default. 20 | return defaultAttribute; 21 | } 22 | return descriptions[0]; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/SHiPSProviderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Reflection.Emit; 4 | 5 | namespace Microsoft.PowerShell.SHiPS 6 | { 7 | /// 8 | /// This attribute is used on SHiPS' derived classes to mark proper actions that SHiPS 9 | /// is expected to take. 10 | /// 11 | [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 12 | public sealed class SHiPSProviderAttribute : Attribute 13 | { 14 | /// 15 | /// True, SHiPS does caching from Get-ChildItem; false otherwise. 16 | /// 17 | public bool UseCache { get; set; } = SHiPSBase.UseCacheDefaultValue; 18 | 19 | /// 20 | /// Gets and sets a flag specifying whether SHiPS needs to Write-Progress. 21 | /// True, SHiPS will call Write-Progress; false it is assumed module will call Write-Progress. 22 | /// 23 | public bool BuiltinProgress { get; set; } = SHiPSBase.BuiltinProgressDefaultValue; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/FamilyTreeInCSharp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FamilyTreeInCSharp", "FamilyTreeInCSharp.csproj", "{8DCEE402-C9D8-4678-A901-27FC0962B63E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8DCEE402-C9D8-4678-A901-27FC0962B63E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8DCEE402-C9D8-4678-A901-27FC0962B63E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8DCEE402-C9D8-4678-A901-27FC0962B63E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8DCEE402-C9D8-4678-A901-27FC0962B63E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation 2 | All rights reserved. 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the Software), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Provider/CollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Text; 7 | 8 | namespace CodeOwls.PowerShell.Provider 9 | { 10 | public static class CollectionExtensions 11 | { 12 | public static string ToArgList(this Collection items) 13 | { 14 | if (null == items) 15 | { 16 | return "()"; 17 | } 18 | 19 | return "(" + String.Join("), (", items.ToArray()) + ")"; 20 | } 21 | 22 | public static string ToArgString(this PSObject o) 23 | { 24 | if (null == o) 25 | { 26 | return ""; 27 | } 28 | return o.BaseObject.ToString(); 29 | } 30 | public static string ToArgString(this object o) 31 | { 32 | if (null == o) 33 | { 34 | return ""; 35 | } 36 | return o.ToString(); 37 | } 38 | 39 | 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/p2f/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | 4 | 5 | Copyright (c) 2014 Code Owls LLC 6 | 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | 10 | of this software and associated documentation files (the "Software"), to deal 11 | 12 | in the Software without restriction, including without limitation the rights 13 | 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | 16 | copies of the Software, and to permit persons to whom the Software is 17 | 18 | furnished to do so, subject to the following conditions: 19 | 20 | 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | 29 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | 33 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 34 | 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | 37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 38 | 39 | SOFTWARE. -------------------------------------------------------------------------------- /samples/ShowProgress/README.md: -------------------------------------------------------------------------------- 1 | # Sample Provider - Show Progress and Other Attributes 2 | 3 | ## Step 1- Install SHiPS 4 | 5 | Follow the instructions [in here][readme] to download and install the SHiPS. 6 | 7 | ## Step 2 - Review the sample code 8 | 9 | See the [ShowProgress module][sp]. 10 | 11 | ## Step 3 - Try it out 12 | 13 | ```powershell 14 | Import-Module SHiPS 15 | Import-Module .\samples\ShowProgress 16 | new-psdrive -name n -psprovider SHiPS -root ShowProgress#NoBuiltinProgress 17 | 18 | cd n: 19 | dir 20 | dir -verbose 21 | ``` 22 | 23 | ## Key takeaways from this example 24 | 25 | - By default SHiPS is not caching data returned from Get-ChildItem 26 | - Sometimes it can be slow when you accessing data store especially through the Internet, you may want to cache the data for better user experience. To do so, you can add an attribute to your class, e.g., 27 | 28 | ```powershell 29 | [SHiPSProvider(UseCache=$true)] 30 | ``` 31 | - By default SHiPS shows progress. However you can disable it by adding the following attribute: 32 | 33 | ```powershell 34 | [SHiPSProvider(BuiltinProgress= $false)] 35 | ``` 36 | - If needed, you can add Write-Progress in your PowerShell module. 37 | 38 | [readme]: ../../README.md#Installing-SHiPS 39 | [sp]:ShowProgress.psm1 40 | -------------------------------------------------------------------------------- /test/automation/SHiPSTest/SHiPSTest.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Assuming you have done clone. Now cd to SHiPS\test\automation folder. Try the following. 3 | 4 | Import-Module ..\..\src\out\SHiPS\SHiPS 5 | Import-Module .\SHiPSTest.psm1 6 | new-psdrive -name jj -psprovider SHiPS -root SHiPSTest#SHiPSTest 7 | cd jj: 8 | dir 9 | 10 | #> 11 | 12 | using namespace Microsoft.PowerShell.SHiPS 13 | $script:PowerShellProcessName = if($IsCoreCLR) {'pwsh'} else{ 'PowerShell'} 14 | 15 | 16 | class SHiPSTest : SHiPSDirectory 17 | { 18 | 19 | SHiPSTest([string]$name): base($name) 20 | { 21 | } 22 | 23 | [object[]] GetChildItem() 24 | { 25 | 26 | $obj = @() 27 | 28 | Write-verbose "You should see this verbose message without -verbose!!" -Verbose 29 | 30 | $ps = get-process $script:PowerShellProcessName 31 | $obj += [SHiPSTestLeaf]::new($ps[0].Name); 32 | 33 | Write-debug "hello debuggggggggggggggggggggg!!" 34 | 35 | 36 | $obj += [SHiPSTest]::new("SHiPSTest"); 37 | $obj += "SHiPSTest222" 38 | 39 | 40 | Write-verbose "hello you have used -verbose!!" 41 | 42 | return $obj; 43 | } 44 | } 45 | 46 | 47 | class SHiPSTestLeaf : SHiPSLeaf 48 | { 49 | SHiPSTestLeaf([string]$name): base($name) 50 | { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/Paths/NullRootPathNode.cs: -------------------------------------------------------------------------------- 1 | using CodeOwls.PowerShell.Provider.PathNodes; 2 | 3 | namespace ProviderFramework_1_TheNullProvider 4 | { 5 | /// 6 | /// the value factory class. 7 | /// 8 | /// used by P2F to manage items for a 9 | /// particular path value. 10 | /// 11 | class NullRootPathNode : PathNodeBase 12 | { 13 | private const string NodeName = "NullRootNode"; 14 | 15 | /// 16 | /// supplies the item for the current path value 17 | /// 18 | /// the item it wrapped in either a PathValue instance 19 | /// that describes the item, its name, and whether it is 20 | /// a container. 21 | /// 22 | /// 23 | /// 24 | /// 25 | public override IPathValue GetNodeValue() 26 | { 27 | var item = new NullItem(); 28 | 29 | return new LeafPathValue( item, Name ); 30 | } 31 | 32 | /// 33 | /// supplies the name for the item at the current path value 34 | /// 35 | public override string Name 36 | { 37 | get { return NullRootPathNode.NodeName; } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/CodeOwls.PowerShell.Paths.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | CodeOwls.PowerShell.Paths 5 | true 6 | true 7 | ../../../../signing/35MSSharedLib1024.snk 8 | true 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IPathValue.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | namespace CodeOwls.PowerShell.Provider.PathNodes 27 | { 28 | public interface IPathValue 29 | { 30 | object Item { get; } 31 | string Name { get; } 32 | bool IsCollection { get; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Provider/CodeOwls.PowerShell.Provider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | CodeOwls.PowerShell.Provider 5 | true 6 | true 7 | ../../../../signing/35MSSharedLib1024.snk 8 | true 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /samples/Library/README.md: -------------------------------------------------------------------------------- 1 | # Sample Provider - Library 2 | 3 | ## Step 1- Install SHiPS 4 | 5 | Follow the instructions [in here][readme] to download and install the SHiPS. 6 | 7 | ## Step 2 - Review the sample code 8 | 9 | See the [Library module][fm]. 10 | 11 | ## Step 3 - Try it out 12 | 13 | ``` powershell 14 | cd \SHiPS 15 | Import-Module SHiPS 16 | Import-Module .\samples\Library\Library.psm1 17 | new-psdrive -name M -psprovider SHiPS -root 'Library#Music' 18 | 19 | cd M: 20 | PS M:\> dir 21 | 22 | Directory: M: 23 | 24 | Mode Name 25 | ---- ---- 26 | + Classic 27 | + Rock 28 | 29 | PS M:\> cd .\Classic\ 30 | PS M:\Classic> Get-Content .\SwanLake 31 | 32 | Tchaikovsky's magical ballet tells ... 33 | 34 | PS M:\Classic>Set-Content .\Nocturnes -Value "Beautiful" 35 | PS M:\Classic> dir 36 | 37 | Directory: MM:\Classic 38 | 39 | Mode Name 40 | ---- ---- 41 | . SwanLake 42 | . BlueDanube 43 | . Nocturnes 44 | 45 | 46 | PS M:\Classic> Get-Content .\Nocturnes 47 | 48 | Beautiful 49 | 50 | ``` 51 | 52 | ## Key Takeaways from this example 53 | 54 | - Demonstrated how to use Get-Content and Set-Content cmdlet 55 | - Get-Content is supported on Leaf node only 56 | - Set-Content is supported on both Leaf and Directory. A child node is created under the current directory if the item does not exist. 57 | 58 | [readme]: ../../README.md#Installing-SHiPS 59 | [fm]: Library.psm1 60 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/NullProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Management.Automation.Provider; 7 | using System.Text; 8 | 9 | namespace ProviderFramework_1_TheNullProvider 10 | { 11 | /// 12 | /// The provider class. 13 | /// 14 | [CmdletProvider("NullProvider", ProviderCapabilities.ShouldProcess)] 15 | public class NullProvider : CodeOwls.PowerShell.Provider.Provider 16 | { 17 | /// 18 | /// a required P2F override 19 | /// 20 | /// supplies P2F with the path processor for this provider 21 | /// 22 | protected override CodeOwls.PowerShell.Paths.Processors.IPathResolver PathResolver 23 | { 24 | get { return new NullPathResolver(); } 25 | } 26 | 27 | /// 28 | /// overridden to supply a default drive when the provider is loaded 29 | /// 30 | protected override Collection InitializeDefaultDrives() 31 | { 32 | return new Collection 33 | { 34 | new NullDrive( 35 | new PSDriveInfo( "Null", ProviderInfo, String.Empty, "Null Drive", null ) 36 | ) 37 | }; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Provider/NullDisposable.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Linq; 27 | using System.Text; 28 | 29 | namespace CodeOwls.PowerShell.Provider 30 | { 31 | class NullDisposable : IDisposable 32 | { 33 | public void Dispose() 34 | { 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IClearItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public interface IClearItem 31 | { 32 | object ClearItemDynamicParamters { get; } 33 | void ClearItem(IProviderContext providerContext, string path); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/ISetItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public interface ISetItem 31 | { 32 | object SetItemParameters { get; } 33 | IPathValue SetItem(IProviderContext providerContext, string path, object value); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IRemoveItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public interface IRemoveItem 31 | { 32 | object RemoveItemParameters { get; } 33 | void RemoveItem(IProviderContext providerContext, string path, bool recurse); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IRenameItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public interface IRenameItem 31 | { 32 | object RenameItemParameters { get; } 33 | void RenameItem(IProviderContext providerContext, string path, string newName); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FamilyTreeInCSharp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FamilyTreeInCSharp")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8dcee402-c9d8-4678-a901-27fc0962b63e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0")] 37 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IInvokeItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System.Collections.Generic; 27 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 28 | 29 | namespace CodeOwls.PowerShell.Provider.PathNodes 30 | { 31 | public interface IInvokeItem 32 | { 33 | object InvokeItemParameters { get; } 34 | IEnumerable InvokeItem(IProviderContext providerContext, string path); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SHiPS")] 9 | [assembly: AssemblyDescription("Simple Hierarchy in PowerShell")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft Corporation")] 12 | [assembly: AssemblyProduct("SHiPS")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ea5e0f26-2b66-4a65-a2d2-44fc36dc0d30")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0")] 37 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | using System.Reflection; 24 | using System.Runtime.CompilerServices; 25 | using System.Runtime.InteropServices; 26 | 27 | [assembly: AssemblyConfiguration("")] 28 | [assembly: AssemblyCompany("Code Owls LLC")] 29 | [assembly: AssemblyCopyright("Copyright © 2016 Code Owls LLC, All Rights Reserved")] 30 | 31 | //[assembly: AssemblyDelaySign(false)] 32 | //[assembly: AssemblyKeyFile("")] 33 | //[assembly: AssemblyKeyName("")] 34 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/ICopyItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public interface ICopyItem 31 | { 32 | object CopyItemParameters { get; } 33 | IPathValue CopyItem(IProviderContext providerContext, string path, string copyPath, IPathValue destinationContainer, bool recurse); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Processors/IPathResolver.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System.Collections.Generic; 27 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 28 | using CodeOwls.PowerShell.Provider.PathNodes; 29 | 30 | namespace CodeOwls.PowerShell.Paths.Processors 31 | { 32 | public interface IPathResolver 33 | { 34 | IEnumerable ResolvePath( IProviderContext providerContext, string path ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/FamilyTree/README.md: -------------------------------------------------------------------------------- 1 | # Sample Provider - FamilyTree 2 | 3 | ## Step 1- Install SHiPS 4 | 5 | Follow the instructions [in here][readme] to download and install the SHiPS. 6 | 7 | ## Step 2 - Review the sample code 8 | 9 | See the [FamilyTree module][fm]. 10 | 11 | ## Step 3 - Try it out 12 | 13 | ```powershell 14 | cd \SHiPS 15 | Import-Module SHiPS 16 | Import-Module .\samples\FamilyTree 17 | 18 | new-psdrive -name Austin -psprovider SHiPS -root 'FamilyTree#Austin' 19 | cd Austin: 20 | dir 21 | cd Ben 22 | 23 | dir | %{$_.data} 24 | 25 | PS Austin:\> dir 26 | 27 | Container: Microsoft.PowerShell.SHiPS\SHiPS::FamilyTree#Austin 28 | 29 | Mode Name 30 | ---- ---- 31 | + Ben 32 | . Bill 33 | 34 | 35 | PS Austin:\>cd Ben 36 | PS Austin:\Ben> 37 | PS Austin:\Ben> dir 38 | 39 | Container: Microsoft.PowerShell.SHiPS\SHiPS::FamilyTree#Austin\Ben 40 | Mode Name 41 | ---- ---- 42 | . Chris 43 | . Cathy 44 | 45 | PS Austin:\Ben>dir | %{$_.Data} 46 | 47 | Name DOB Gender 48 | ---- --- ------ 49 | Chris 5034 M 50 | Cathy 5050 F 51 | 52 | ``` 53 | 54 | ## Key Takeaways from this example 55 | 56 | - Demonstrated how to use a node property 57 | - We defined a class, named as `Person`. 58 | - In the type Chris and Cathy, we exposed $Data field as a node's property 59 | - When a user `dir` under Ben, it will show two child nodes, Chris and Cathy. But if you do `dir | fl *`, you will see a `Data` property which contains more data about the node. 60 | 61 | [readme]: ../../README.md#Installing-SHiPS 62 | [fm]: FamilyTree.psm1 63 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample2_TypeProvider/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProviderFramework_2_TypeProvider")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ProviderFramework_2_TypeProvider")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dfb03b69-9309-4f09-b589-cabde2ee9256")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample3_TypeProvider/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProviderFramework_3_TypeProvider")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ProviderFramework_3_TypeProvider")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("22763c59-39e4-4a44-a064-79bc16049316")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProviderFramework_1_TheNullProvider")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ProviderFramework_1_TheNullProvider")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("92c08169-b6d9-460b-852b-37f6f06972ba")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/FamilyTreeInCSharp.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.PowerShell.SHiPS; 3 | 4 | namespace FamilyTreeInCSharp 5 | { 6 | 7 | /// 8 | /// A class defines the family tree root. 9 | /// 10 | public class Root : SHiPSDirectory 11 | { 12 | public Root(string name) : base(name) 13 | { 14 | } 15 | 16 | public override object[] GetChildItem() 17 | { 18 | return new List 19 | { 20 | new Erin("Erin"), 21 | new Ethen("Ethen") 22 | }.ToArray(); 23 | } 24 | } 25 | 26 | /// 27 | /// Defines a node with children. 28 | /// 29 | public class Erin : SHiPSDirectory 30 | { 31 | public Erin(string name) : base(name) 32 | { 33 | } 34 | 35 | public override object[] GetChildItem() 36 | { 37 | return new object[] { new Mike("Erin's kid")}; 38 | } 39 | } 40 | 41 | /// 42 | /// Defines a node with children. 43 | /// 44 | public class Mike : SHiPSDirectory 45 | { 46 | public Mike(string name) : base(name) 47 | { 48 | } 49 | 50 | public override object[] GetChildItem() 51 | { 52 | return new object[] {"Hello I am Mike."}; 53 | } 54 | } 55 | 56 | /// 57 | /// Defines a leaf node. 58 | /// 59 | public class Ethen : SHiPSLeaf 60 | { 61 | public Ethen(string name) : base(name) 62 | { 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/INewItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System.Collections.Generic; 27 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 28 | 29 | namespace CodeOwls.PowerShell.Provider.PathNodes 30 | { 31 | public interface INewItem 32 | { 33 | IEnumerable NewItemTypeNames { get; } 34 | object NewItemParameters { get; } 35 | IPathValue NewItem(IProviderContext providerContext, string path, string itemTypeName, object newItemValue); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.1.3.{build} 2 | 3 | environment: 4 | # Avoid expensive initialization of dotnet cli, see: http://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds 5 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 6 | matrix: 7 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 8 | PowerShellEdition: Desktop 9 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 10 | PowerShellEdition: Core 11 | 12 | configuration: Release 13 | platform: Any CPU 14 | 15 | # clone directory 16 | clone_folder: c:\projects\ships 17 | 18 | init: 19 | - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) 20 | 21 | 22 | # Install Pester 23 | install: 24 | - cinst -y pester 25 | 26 | # to run your custom scripts instead of automatic MSBuild 27 | build_script: 28 | 29 | - git submodule update --init 30 | - ps: cd .\src; .\bootstrap.ps1; .\build.ps1 Release 31 | 32 | 33 | 34 | # Run Pester tests and store the results 35 | test_script: 36 | - ps: | 37 | Import-Module c:\projects\ships\tools\setup.psm1 38 | Invoke-SHiPSTest 39 | 40 | 41 | # Upload the project along with TestResults as a zip archive 42 | on_finish: 43 | - ps: | 44 | 45 | @( 46 | # You can add other artifacts here 47 | "C:\projects\ships\src\out\SHiPS.zip" 48 | ) | % { Push-AppveyorArtifact $_ } 49 | 50 | Get-ChildItem -Path c:\projects\ships\test\ -Filter 'TestResults*.xml' -File | ForEach-Object { 51 | (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", "$($_.FullName)") 52 | } 53 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Attributes/CmdletHelpPathIDAttribute.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System; 27 | 28 | namespace CodeOwls.PowerShell.Provider.Attributes 29 | { 30 | [AttributeUsage( AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 31 | public class CmdletHelpPathIDAttribute : Attribute 32 | { 33 | public CmdletHelpPathIDAttribute( string id) 34 | { 35 | ID = id; 36 | } 37 | 38 | public string ID { get; private set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | using System.Reflection; 26 | using System.Runtime.CompilerServices; 27 | using System.Runtime.InteropServices; 28 | 29 | // 30 | // General Information about an assembly is controlled through the following 31 | // set of attributes. Change these attribute values to modify the information 32 | // associated with an assembly. 33 | // 34 | [assembly: AssemblyProduct("Code Owls LLC PowerShell Library")] 35 | 36 | [assembly: AssemblyVersion("1.6.1")] 37 | [assembly: AssemblyFileVersion("1.6.1")] 38 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/ProviderContext.cs: -------------------------------------------------------------------------------- 1 | using CodeOwls.PowerShell.Paths.Extensions; 2 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 3 | 4 | namespace Microsoft.PowerShell.SHiPS 5 | { 6 | 7 | /// 8 | /// Stores the SHiPS provider's the context data for PowerShell modules to use. 9 | /// 10 | public class ProviderContext 11 | { 12 | /// 13 | /// Gets the force property. 14 | /// 15 | public bool Force { get; internal set; } 16 | 17 | /// 18 | /// Gets the recurse property. 19 | /// 20 | public bool Recurse { get; internal set; } 21 | 22 | /// 23 | /// Gets the filter property that was supplied by a user. 24 | /// 25 | public string Filter { get; internal set; } 26 | 27 | /// 28 | /// Dynamic parameters passed in from commandline. 29 | /// 30 | public object DynamicParameters { get; internal set; } 31 | 32 | /// 33 | /// Cmdlet bound parameters. 34 | /// 35 | public object BoundParameters { get; internal set; } 36 | 37 | internal void Set(IProviderContext context) 38 | { 39 | Force = context.Force; 40 | Recurse = context.Recurse; 41 | Filter = context.Filter; 42 | DynamicParameters = context.DynamicParameters; 43 | } 44 | 45 | internal void Clear() 46 | { 47 | Force = false; 48 | Recurse = false; 49 | Filter = null; 50 | DynamicParameters = null; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ThirdPartyNotices.txt: -------------------------------------------------------------------------------- 1 | THIRD-PARTY SOFTWARE NOTICES AND INFORMATION 2 | 3 | Do Not Translate or Localize 4 | 5 | This product incorporates copyrighted material from the open source projects 6 | listed below (Third Party IP). The license terms of Microsoft Corporation’s 7 | product do not apply to the Third Party IP which is licensed to you under its 8 | original license terms which are provided below. Microsoft reserves all rights 9 | not expressly granted herein, whether by implication, estoppel or otherwise. 10 | You may find a copy of the Corresponding Source code distributed as part of 11 | this tool. 12 | 13 | The MIT License (MIT) 14 | 15 | Copyright (c) 2014 Code Owls LLC 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copyof 18 | this software and associated documentation files (the "Software"), to dealin 19 | the Software without restriction, including without limitation the rightsto 20 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 21 | of the Software, and to permit persons to whom the Software is furnished to do 22 | so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in all 25 | copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | SOFTWARE. 34 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/PSObjectNodeService.cs: -------------------------------------------------------------------------------- 1 | using System.Management.Automation; 2 | using CodeOwls.PowerShell.Paths.Extensions; 3 | using CodeOwls.PowerShell.Provider.PathNodes; 4 | 5 | namespace Microsoft.PowerShell.SHiPS 6 | { 7 | /// 8 | /// Defines actions that applies to a PSObject node. 9 | /// 10 | internal class PSObjectNodeService : PathNodeBase 11 | { 12 | private readonly PSObject _pso; 13 | private string _name = null; 14 | private static readonly string _leaf = "."; 15 | 16 | internal PSObjectNodeService(object pso) 17 | { 18 | _pso = pso as PSObject; 19 | } 20 | 21 | public override IPathValue GetNodeValue() 22 | { 23 | //PSObjects are the leaf nodes only 24 | return new LeafPathValue(_pso, Name); 25 | } 26 | 27 | public override string ItemMode 28 | { 29 | get 30 | { 31 | return _leaf; 32 | } 33 | } 34 | 35 | public override string Name 36 | { 37 | get 38 | { 39 | if (_name != null) { return _name;} 40 | if (_pso != null) 41 | { 42 | //When name contains slash, it breaks provider navigation or caching. calling MakeSafeForPath() 43 | //to replace slash with '-' before caching it. Otherwise, we will get cache missing. 44 | _name = _pso.SafeGetPropertyValue("Name", () => _pso.ToString())?.ToString().MakeSafeForPath(); 45 | return _name; 46 | } 47 | 48 | return string.Empty; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/IPathNode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System.Collections.Generic; 27 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 28 | 29 | namespace CodeOwls.PowerShell.Provider.PathNodes 30 | { 31 | public interface IPathNode 32 | { 33 | IEnumerable Resolve( IProviderContext providerContext, string name ); 34 | IPathValue GetNodeValue(); 35 | IEnumerable GetNodeChildren(IProviderContext providerContext); 36 | object GetNodeChildrenParameters { get; } 37 | string Name { get; } 38 | 39 | string ItemMode { get; } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/Modules/SHiPS.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | RootModule= 'Microsoft.PowerShell.SHiPS.dll' 3 | ModuleVersion = '0.8.1' 4 | GUID = 'A5FE6B04-385F-470F-9347-66EB3645B422' 5 | Author = 'Microsoft Corporation' 6 | CompanyName = 'Microsoft Corporation' 7 | Copyright = '© Microsoft Corporation. All rights reserved.' 8 | Description = 'SHiPS is a PowerShell provider. More accurately it is a provider platform that simplifies developing PowerShell providers.' 9 | PowerShellVersion = '5.0' 10 | DotNetFrameworkVersion = '4.7.1' 11 | FormatsToProcess = @( 'SHiPS.formats.ps1xml' ) 12 | CmdletsToExport = @() 13 | VariablesToExport = @() 14 | AliasesToExport = @() 15 | DscResourcesToExport = @() 16 | 17 | PrivateData = @{ 18 | PSData = @{ 19 | Tags = @('SHiPS', 'PSEdition_Core', 'PSEdition_Desktop', 'Linux', 'Mac') 20 | ProjectUri = 'https://github.com/PowerShell/SHiPS' 21 | ReleaseNotes = @' 22 | 23 | ## 0.8.1 24 | * Added Get-Content and Set-Content. 25 | ## 0.8.0 26 | * Changed to single .NET Standard 2.0 assembly 27 | * Added error handling for unspported provider cmdlets. 28 | ## 0.7.2 29 | * Bug fix for 'dir -force' case. 30 | ## 0.7.1 31 | * Perf improvement. For providers using cached data, [SHiPSProvider(UseCache=$true)], 'dir -force' will only refresh the last node in the path. 32 | * Allowed to navigate home directory, e.g., 'dir ~' or 'cd ~' under SHiPS based provider drive. 33 | ## 0.7.0 34 | * Fixed forward slash issue on Linux. 35 | * Fixed Set-Location drive: path issue on Linux. 36 | ## 0.6.0 37 | * Fixed Test-Path cmdlet. 38 | * Updated SHiPS to build with .NET Core 2.0.5 to be in sync with pwsh. 39 | * Fixed SHiPS formats.ps1xml. 40 | '@ 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/SHiPSDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CodeOwls.PowerShell.Provider.PathNodes; 4 | 5 | namespace Microsoft.PowerShell.SHiPS 6 | { 7 | 8 | /// 9 | /// Defines a type that represents a node object which contains any child items. 10 | /// 11 | public class SHiPSDirectory : SHiPSBase 12 | { 13 | // Contains all child items of the current node. 14 | internal Dictionary> Children = new Dictionary>(StringComparer.OrdinalIgnoreCase); 15 | 16 | /// 17 | /// Default C'tor. 18 | /// 19 | public SHiPSDirectory() 20 | { 21 | } 22 | 23 | /// 24 | /// C'tor. 25 | /// 26 | /// Name of the node. 27 | public SHiPSDirectory(string name) : base (name, isLeaf:false) 28 | { 29 | } 30 | 31 | /// 32 | /// It is expected that the drive class in PowerShell implements the GetChildItem(). 33 | /// 34 | /// 35 | public virtual object[] GetChildItem() 36 | { 37 | return null; 38 | } 39 | 40 | /// 41 | /// Gets the dynamic parameters for the get-childitem cmdlet. 42 | /// 43 | /// 44 | public virtual object GetChildItemDynamicParameters() 45 | { 46 | return null; 47 | } 48 | 49 | /// 50 | /// True if the current item has been visisted. This info is useful for cached case. 51 | /// 52 | internal bool ItemNavigated { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/FileSystem/FileSystem.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Modeling the FileSystem 3 | 4 | Try it: 5 | Assuming you have done git clone and run build.ps1, cd to your git clone folder and try the following. 6 | 7 | Import-Module SHiPS 8 | Import-Module .\samples\FileSystem.psm1 9 | new-psdrive -name FS -psprovider SHiPS -root FileSystem#Home 10 | cd FS: 11 | dir 12 | 13 | #> 14 | 15 | using namespace Microsoft.PowerShell.SHiPS 16 | 17 | 18 | [SHiPSProvider(BuiltinProgress=$false)] 19 | class Home : SHiPSDirectory 20 | { 21 | Hidden [object]$data = $null 22 | 23 | Home([string]$name): base($name) 24 | { 25 | } 26 | 27 | Home ([string]$name, [object]$data) : base ($name) 28 | { 29 | $this.data = $data 30 | } 31 | 32 | 33 | [object[]] GetChildItemImpl([string] $data) 34 | { 35 | $obj = @() 36 | 37 | Write-Verbose $data 38 | 39 | dir $data | ForEach-Object { 40 | 41 | if($_.PSIsContainer) 42 | { 43 | $obj+=[Home]::new($_.Name, $_.FullName) 44 | } 45 | else 46 | { 47 | $obj+=[CLeaf]::new($_.Name) 48 | } 49 | 50 | } 51 | 52 | return $obj 53 | } 54 | 55 | [object[]] GetChildItem() 56 | { 57 | 58 | $obj = @() 59 | 60 | if($this.data) 61 | { 62 | return $this.GetChildItemImpl($this.data) 63 | } 64 | else 65 | { 66 | $driveName = $this.GetType().Name 67 | Write-Verbose "Operating on $driveName" 68 | 69 | return $this.GetChildItemImpl("~") 70 | } 71 | 72 | return $obj; 73 | } 74 | } 75 | 76 | class CLeaf : SHiPSLeaf 77 | { 78 | CLeaf([string]$name): base($name) 79 | { 80 | } 81 | } -------------------------------------------------------------------------------- /test/adhoc/adhoc1.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Assuming you clone to E:\azure\ 3 | 4 | Import-Module ..\SHiPS.psd1 5 | Import-Module .\adhoc1.psm1 6 | new-psdrive -name JJ -psprovider SHiPS -root adhoc1#Root 7 | 8 | cd JJ: 9 | dir 10 | 11 | test: 12 | ipmo will show the psxml foramt file is found and loaded. 13 | #> 14 | 15 | using namespace Microsoft.PowerShell.SHiPS 16 | 17 | $MyInvocation 18 | 19 | class Root : SHiPSDirectory 20 | { 21 | Root([string]$name): base($name){} 22 | 23 | Root ([string]$name, [object]$nodeProperty) : base ($name) {} 24 | 25 | [object[]] GetChildItem() 26 | { 27 | 28 | #the following two lines are evil to see it breaks or hangs 29 | $MyInvocation 30 | ipmo -force azurerm.resources -Debug -verbose 31 | 32 | $obj = @() 33 | $obj += [Austin]::new("Bill", "PowerShell"); 34 | $obj += [Chris]::new("William"); 35 | return $obj 36 | } 37 | } 38 | 39 | class Austin : SHiPSDirectory 40 | { 41 | Hidden [object]$data = $null 42 | 43 | Austin([string]$name): base($name) 44 | { 45 | } 46 | 47 | Austin ([string]$name, [object]$data) : base ($name) 48 | { 49 | $this.data = $data 50 | } 51 | 52 | [object] Funny() 53 | { 54 | return Get-Service BITS 55 | } 56 | 57 | [object[]] GetChildItem() 58 | { 59 | $obj = @() 60 | # $data gets set when the object gets created. Through this we pass around the data from parent node to child 61 | $processes = Get-Process $this.data 62 | foreach ($p in $processes) { 63 | $obj += $p; 64 | break; 65 | } 66 | 67 | # from function call 68 | $result = $this.Funny() 69 | $obj += $result; 70 | 71 | # child class 72 | $obj += [Chris]::new("Hello Chris"); 73 | 74 | return $obj; 75 | } 76 | } 77 | 78 | 79 | class Chris : SHiPSLeaf 80 | { 81 | Chris([string]$name): base($name) 82 | { 83 | } 84 | } -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Provider/Drive.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System; 27 | using System.Linq; 28 | using System.Management.Automation; 29 | using System.Text.RegularExpressions; 30 | using CodeOwls.PowerShell.Paths.Processors; 31 | using CodeOwls.PowerShell.Provider.PathNodes; 32 | 33 | namespace CodeOwls.PowerShell.Provider 34 | { 35 | public abstract class Drive : PSDriveInfo 36 | { 37 | public Drive(PSDriveInfo driveInfo) 38 | : base(driveInfo) 39 | { 40 | } 41 | 42 | internal static string GetDriveName(string path) 43 | { 44 | Regex re = new Regex( @"^([^:]+):"); 45 | var match = re.Match(path); 46 | if( ! match.Success) 47 | { 48 | return null; 49 | } 50 | 51 | return match.Groups[1].Value; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Microsoft.PowerShell.SHiPS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | true 6 | true 7 | Microsoft.PowerShell.SHiPS 8 | ../signing/35MSSharedLib1024.snk 9 | true 10 | Microsoft.PowerShell.SHiPS 11 | 12 | portable 13 | 14 | false 15 | false 16 | false 17 | false 18 | false 19 | false 20 | false 21 | false 22 | 23 | $(DefineConstants);CORECLR 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Processors/PathResolverDecorator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System.Collections.Generic; 25 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 26 | using CodeOwls.PowerShell.Provider.PathNodes; 27 | 28 | namespace CodeOwls.PowerShell.Paths.Processors 29 | { 30 | public abstract class PathResolverDecorator : IPathResolver 31 | { 32 | private readonly IPathResolver _basePathResolver; 33 | 34 | public PathResolverDecorator(IPathResolver basePathResolver) 35 | { 36 | _basePathResolver = basePathResolver; 37 | } 38 | 39 | #region Implementation of IPathResolver 40 | 41 | public virtual IEnumerable ResolvePath( IProviderContext providerContext, string path) 42 | { 43 | return _basePathResolver.ResolvePath( providerContext, path); 44 | } 45 | 46 | #endregion 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Extensions/PathStringExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System; 27 | using System.Text.RegularExpressions; 28 | 29 | namespace CodeOwls.PowerShell.Paths.Extensions 30 | { 31 | public static class PathStringExtensions 32 | { 33 | public static string MakeSafeForPath( this string path ) 34 | { 35 | return String.IsNullOrEmpty(path) 36 | ? path 37 | : path.Replace('\\', '-') 38 | .Replace('/', '-') 39 | .Replace("&", "") 40 | .Replace("…", ""); 41 | } 42 | 43 | public static bool ContainsNodeName( this string path, string nodeName ) 44 | { 45 | var pattern = String.Format(@"(?:^|[:\\\\/]){0}(?:[\\\\/]+|$)", Regex.Escape(nodeName)); 46 | return Regex.IsMatch(path, pattern, RegexOptions.IgnoreCase); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/NodeDoesNotSupportCmdletException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System; 25 | using System.Runtime.Serialization; 26 | 27 | namespace CodeOwls.PowerShell.Paths.Exceptions 28 | { 29 | [Serializable] 30 | public class NodeDoesNotSupportCmdletException : ProviderException 31 | { 32 | // 33 | // For guidelines regarding the creation of new exception types, see 34 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 35 | // and 36 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 37 | // 38 | 39 | public NodeDoesNotSupportCmdletException(string path, string cmdlet) : base( 40 | String.Format( "The node at path '{0}' does not support the cmdlet '{1}'", path, cmdlet) 41 | ) 42 | { 43 | } 44 | 45 | protected NodeDoesNotSupportCmdletException( 46 | SerializationInfo info, 47 | StreamingContext context) : base(info, context) 48 | { 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Utility/ProgressTracker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 4 | 5 | namespace Microsoft.PowerShell.SHiPS 6 | { 7 | internal class ProgressTracker 8 | { 9 | private readonly int _progressId; 10 | private readonly string _activity; 11 | private readonly string _description; 12 | private bool _builtinProgress; 13 | private ProgressRecord _progressRecord; 14 | 15 | internal ProgressTracker(int progressId, string activity, string description, bool builtinProgress) 16 | { 17 | _progressId = progressId; 18 | _activity = activity; 19 | _description = description; 20 | _builtinProgress = builtinProgress; 21 | } 22 | 23 | internal void Start(IProviderContext context) 24 | { 25 | if(!_builtinProgress) { return; } 26 | 27 | _progressRecord = new ProgressRecord(_progressId, _activity, _description) 28 | { 29 | PercentComplete = 0, 30 | RecordType = ProgressRecordType.Processing 31 | }; 32 | context.WriteProgress(_progressRecord); 33 | } 34 | 35 | internal void Update(int percentComplete, IProviderContext context) 36 | { 37 | if (!_builtinProgress) { return; } 38 | if (_progressRecord != null) 39 | { 40 | _progressRecord.PercentComplete = Math.Min(percentComplete, 95); 41 | context.WriteProgress(_progressRecord); 42 | } 43 | } 44 | 45 | internal void End(IProviderContext context) 46 | { 47 | if (!_builtinProgress) { return; } 48 | 49 | try 50 | { 51 | if (_progressRecord != null) 52 | { 53 | _progressRecord.PercentComplete = 100; 54 | _progressRecord.RecordType = ProgressRecordType.Completed; 55 | context.WriteProgress(_progressRecord); 56 | _builtinProgress = false; 57 | } 58 | } 59 | catch (PipelineStoppedException) 60 | { 61 | //noop 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/PathValue.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using CodeOwls.PowerShell.Paths.Extensions; 27 | 28 | namespace CodeOwls.PowerShell.Provider.PathNodes 29 | { 30 | public class ContainerPathValue : PathValue 31 | { 32 | public ContainerPathValue(object item, string name) : base(item, name, true) 33 | { 34 | } 35 | } 36 | 37 | public class LeafPathValue : PathValue 38 | { 39 | public LeafPathValue(object item, string name) : base(item, name, false) 40 | { 41 | } 42 | } 43 | 44 | public class PathValue : IPathValue 45 | { 46 | public PathValue( object item, string name, bool isContainer ) 47 | { 48 | Item = item; 49 | Name = name; 50 | IsCollection = isContainer; 51 | } 52 | public object Item 53 | { 54 | get; 55 | private set; 56 | } 57 | 58 | private string _name; 59 | 60 | public string Name 61 | { 62 | get { return _name.MakeSafeForPath(); } 63 | private set { _name = value; } 64 | } 65 | 66 | public bool IsCollection 67 | { 68 | get; 69 | private set; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample3_TypeProvider/TypeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Management.Automation.Provider; 7 | using System.Reflection; 8 | using CodeOwls.PowerShell.Paths.Processors; 9 | using CodeOwls.PowerShell.Provider; 10 | using CodeOwls.PowerShell.Provider.PathNodes; 11 | 12 | namespace ProviderFramework_3_TypeProvider 13 | { 14 | [CmdletProvider("Types", ProviderCapabilities.ShouldProcess )] 15 | public class TypeProvider : Provider 16 | { 17 | protected override IPathResolver PathResolver 18 | { 19 | get { return new PathResolver(); } 20 | } 21 | 22 | protected override System.Collections.ObjectModel.Collection InitializeDefaultDrives() 23 | { 24 | var driveInfo = new PSDriveInfo( "Types", ProviderInfo, String.Empty, "Provider for loaded .NET assemblies and types", null ); 25 | return new Collection{ new TypeDrive( driveInfo )}; 26 | } 27 | } 28 | 29 | public class TypeDrive : Drive 30 | { 31 | public TypeDrive(PSDriveInfo driveInfo) : base(driveInfo) 32 | { 33 | } 34 | } 35 | 36 | class PathResolver : PathResolverBase 37 | { 38 | protected override IPathNode Root 39 | { 40 | get { return new AppDomainPathNode(); } 41 | } 42 | } 43 | 44 | class AssemblyPathNode : PathNodeBase 45 | { 46 | private readonly Assembly _assembly; 47 | 48 | public AssemblyPathNode( Assembly assembly ) 49 | { 50 | _assembly = assembly; 51 | } 52 | 53 | public override IPathValue GetNodeValue() 54 | { 55 | return new ContainerPathValue( _assembly, Name ); 56 | } 57 | 58 | public override string Name 59 | { 60 | get { return _assembly.GetName().Name; } 61 | } 62 | 63 | public override IEnumerable GetNodeChildren(CodeOwls.PowerShell.Provider.PathNodeProcessors.IProviderContext providerContext) 64 | { 65 | return from type in _assembly.GetExportedTypes() 66 | select new TypePathNode(type) as IPathNode; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/ContentHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Management.Automation.Provider; 4 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 5 | 6 | namespace Microsoft.PowerShell.SHiPS 7 | { 8 | /// 9 | /// Utility class for handling Get-Content and Set-Content. 10 | /// 11 | internal class ContentHelper 12 | { 13 | private readonly SHiPSBase _node; 14 | private readonly SHiPSDrive _drive; 15 | 16 | internal ContentHelper(SHiPSBase node, SHiPSDrive drive) 17 | { 18 | _node = node; 19 | _drive = drive; 20 | } 21 | 22 | #region IGetItemContent 23 | 24 | public IContentReader GetContentReader(IProviderContext context) 25 | { 26 | // Calling GetContent() 27 | var script = Constants.ScriptBlockWithParam1.StringFormat(Constants.GetContent); 28 | var results = PSScriptRunner.InvokeScriptBlock(context, _node, _drive, script, PSScriptRunner.ReportErrors); 29 | 30 | // Expected a collection of strings returned from GetContent() and save it to a stream 31 | var stream = new ContentReader(results, context); 32 | return stream; 33 | } 34 | 35 | public object GetContentReaderDynamicParameters(IProviderContext context) 36 | { 37 | return null; 38 | } 39 | 40 | #endregion 41 | 42 | #region ISetItemContent 43 | 44 | public IContentWriter GetContentWriter(IProviderContext context) 45 | { 46 | var stream = new ContentWriter(context, _drive, _node); 47 | return stream; 48 | } 49 | 50 | public object GetContentWriterDynamicParameters(IProviderContext context) 51 | { 52 | return null; 53 | } 54 | 55 | #endregion 56 | 57 | #region IClearItemContent 58 | 59 | public void ClearContent(IProviderContext providerContext) 60 | { 61 | // Define ClearContent for now as the PowerShell engine calls ClearContent first for Set-Content cmdlet. 62 | return; 63 | } 64 | 65 | public object ClearContentDynamicParameters(IProviderContext providerContext) 66 | { 67 | return null; 68 | } 69 | 70 | #endregion 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/CopyOrMoveToExistingItemException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | using System; 26 | using System.Runtime.Serialization; 27 | 28 | namespace CodeOwls.PowerShell.Paths.Exceptions 29 | { 30 | [Serializable] 31 | public class CopyOrMoveToExistingItemException : ProviderException 32 | { 33 | // 34 | // For guidelines regarding the creation of new exception types, see 35 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 36 | // and 37 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 38 | // 39 | 40 | public CopyOrMoveToExistingItemException() 41 | { 42 | 43 | } 44 | 45 | public CopyOrMoveToExistingItemException(string copyPath) 46 | : base("An item exists at [" + copyPath + "], you must use the -Force parameter to copy or move an item to this location.") 47 | { 48 | } 49 | 50 | protected CopyOrMoveToExistingItemException( 51 | SerializationInfo info, 52 | StreamingContext context) : base(info, context) 53 | { 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/CopyOrMoveToNonexistentContainerException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Runtime.Serialization; 25 | 26 | namespace CodeOwls.PowerShell.Paths.Exceptions 27 | { 28 | [Serializable] 29 | public class CopyOrMoveToNonexistentContainerException : ProviderException 30 | { 31 | // 32 | // For guidelines regarding the creation of new exception types, see 33 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 34 | // and 35 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 36 | // 37 | 38 | public CopyOrMoveToNonexistentContainerException() 39 | { 40 | } 41 | 42 | public CopyOrMoveToNonexistentContainerException(string copyPath) 43 | : base("No item container exists at [" + copyPath + "], you cannot copy or move items there.") 44 | { 45 | } 46 | 47 | protected CopyOrMoveToNonexistentContainerException( 48 | SerializationInfo info, 49 | StreamingContext context) 50 | : base(info, context) 51 | { 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/CopyOrMoveItemInternalException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System; 25 | using System.Runtime.Serialization; 26 | 27 | namespace CodeOwls.PowerShell.Paths.Exceptions 28 | { 29 | [Serializable] 30 | public class CopyOrMoveItemInternalException : ProviderException 31 | { 32 | // 33 | // For guidelines regarding the creation of new exception types, see 34 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 35 | // and 36 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 37 | // 38 | 39 | public CopyOrMoveItemInternalException() 40 | { 41 | 42 | } 43 | 44 | public CopyOrMoveItemInternalException(string path, string copyPath, Exception e) 45 | : base( String.Format("An internal error occurred attempting to copy or move the item at [{0}] to [{1}].", path, copyPath), e ) 46 | { 47 | } 48 | 49 | protected CopyOrMoveItemInternalException( 50 | SerializationInfo info, 51 | StreamingContext context) 52 | : base(info, context) 53 | { 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/ProviderException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | 27 | using System; 28 | using System.Management.Automation; 29 | using System.Runtime.Serialization; 30 | 31 | namespace CodeOwls.PowerShell.Paths.Exceptions 32 | { 33 | [Serializable] 34 | public class ProviderException : RuntimeException 35 | { 36 | // 37 | // For guidelines regarding the creation of new exception types, see 38 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 39 | // and 40 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 41 | // 42 | 43 | public ProviderException() 44 | { 45 | } 46 | 47 | public ProviderException(string message) 48 | : base(message) 49 | { 50 | } 51 | 52 | public ProviderException(string message, Exception inner) 53 | : base(message, inner) 54 | { 55 | } 56 | 57 | protected ProviderException( 58 | SerializationInfo info, 59 | StreamingContext context) 60 | : base(info, context) 61 | { 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/CopyOrMoveToDifferentContainerTypeException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Runtime.Serialization; 25 | 26 | namespace CodeOwls.PowerShell.Paths.Exceptions 27 | { 28 | [Serializable] 29 | public class CopyOrMoveToDifferentContainerTypeException : ProviderException 30 | { 31 | // 32 | // For guidelines regarding the creation of new exception types, see 33 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 34 | // and 35 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 36 | // 37 | 38 | public CopyOrMoveToDifferentContainerTypeException() 39 | { 40 | } 41 | 42 | public CopyOrMoveToDifferentContainerTypeException(string copy, string copyPath) 43 | : base("The item at [" + copy + "] cannot be copied to the specified location ["+copyPath+"] because the destination contains different types of items.") 44 | { 45 | } 46 | 47 | protected CopyOrMoveToDifferentContainerTypeException( 48 | SerializationInfo info, 49 | StreamingContext context) 50 | : base(info, context) 51 | { 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/DynamicParameter/README.md: -------------------------------------------------------------------------------- 1 | # Sample Provider - How to use dynamic parameters 2 | 3 | ## Step 1- Install SHiPS 4 | 5 | Follow the instructions [in here][readme] to download and install the SHiPS. 6 | 7 | ## Step 2 - Model the system 8 | 9 | Let's say we want to model a tree as follows: 10 | 11 | ```powershell 12 | 13 | Nature 14 | - Plant 15 | - Birch 16 | - Maple 17 | - Oak 18 | - Creature 19 | - Cat 20 | - Dog 21 | - Husky 22 | - Bulldog 23 | ``` 24 | 25 | ## Step 3 - Review the sample code 26 | 27 | See the [DynamicParameterSample module][ds]. 28 | 29 | ## Step 4 - Try it out 30 | 31 | ```powershell 32 | Import-Module SHiPS 33 | Import-Module .\samples\DynamicParameter 34 | 35 | new-psdrive -name n -psprovider SHiPS -root DynamicParameter#Nature 36 | cd n: 37 | dir 38 | 39 | dir -Type Plant 40 | 41 | dir -Type Creature 42 | 43 | dir -Filter p* -recurse 44 | 45 | <# 46 | The output looks like the following. 47 | PS n:\>dir 48 | 49 | Mode Name 50 | ---- ---- 51 | + Plant 52 | + Creature 53 | 54 | PS n:\>dir -Type Plant 55 | 56 | Container: Microsoft.PowerShell.SHiPS\SHiPS::DynamicParameterSample#Nature 57 | 58 | Mode Name 59 | ---- ---- 60 | + Plant 61 | 62 | PS n:\> dir -Type Creature 63 | 64 | Container: Microsoft.PowerShell.SHiPS\SHiPS::DynamicParameterSample#Nature 65 | 66 | Mode Name 67 | ---- ---- 68 | + Creature 69 | 70 | PS n:\> cd .\Creature\ 71 | PS n:\Creature>dir -Filter p* -recurse 72 | Pointer 73 | Poodle 74 | Pug 75 | Pomeranian 76 | Pui 77 | Pumi 78 | 79 | #> 80 | ``` 81 | 82 | ## Key takeaways from this example 83 | 84 | - Other than built-in parameters in Get-ChildItem, author can add dynamic parameters 85 | - Define it as a class 86 | - Add `[Parameter()]` in a dynamic parameter. That's it. 87 | 88 | - Define `[object] GetChildItemDynamicParameters()` method and return a instance of the class that defines your dynamic parameters 89 | - To get whether a user specifies any dynamic parameters, you can use `$this.ProviderContext.DynamicParameters`. 90 | - `Filter` is a built-in parameter. 91 | 92 | Sometimes you want to have server-side search for better user experience, 93 | you can get the query string via `$this.ProviderContext.Filter`. 94 | The value of Filter here is ``foobar*`` from -Filter ``foobar*`` 95 | 96 | [readme]: ../../README.md#Installing-SHiPS 97 | [ds]:DynamicParameter.psm1 98 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Exceptions/MamlHelpDocumentExistsButCannotBeLoadedException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | using System; 26 | using System.Runtime.Serialization; 27 | 28 | namespace CodeOwls.PowerShell.Paths.Exceptions 29 | { 30 | [Serializable] 31 | public class MamlHelpDocumentExistsButCannotBeLoadedException : ProviderException 32 | { 33 | // 34 | // For guidelines regarding the creation of new exception types, see 35 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 36 | // and 37 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 38 | // 39 | 40 | public MamlHelpDocumentExistsButCannotBeLoadedException() 41 | { 42 | } 43 | 44 | public MamlHelpDocumentExistsButCannotBeLoadedException(string filename, Exception e) 45 | : base(String.Format( "The custom MAML help file '{0}' exists, but cannot be loaded by the XML parser. Verify the file is valid MAML.", filename), e) 46 | { 47 | } 48 | 49 | protected MamlHelpDocumentExistsButCannotBeLoadedException( 50 | SerializationInfo info, 51 | StreamingContext context) : base(info, context) 52 | { 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/SHiPSConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.PowerShell.SHiPS 2 | { 3 | internal static class ErrorId 4 | { 5 | internal static readonly string InvalidRootFormat = "InvalidRootFormat"; 6 | internal static readonly string CannotGetModule = "CannotGetModule"; 7 | internal static readonly string CannotCreateInstance = "CannotCreateInstance"; 8 | internal static readonly string RootNodeTypeMustBeContainer = "RootNodeTypeMustBeContainer"; 9 | internal static readonly string NodeNameIsNullOrEmpty = "NodeNameIsNullOrEmpty"; 10 | internal static readonly string NewDriveRootDoesNotExist = "NewDriveRootDoesNotExist"; 11 | internal static readonly string NotContainerNode = "NotContainerNode"; 12 | internal static readonly string SetContentNotSupportedErrorId = "SetContent.NotSupported"; 13 | 14 | } 15 | 16 | internal static class Constants 17 | { 18 | internal static readonly string Leaf = "Leaf"; 19 | internal static readonly string GetChildItemDynamicParameters = "GetChildItemDynamicParameters"; 20 | internal static readonly string InvokeItemDynamicParameters = "InvokeItemDynamicParameters"; 21 | internal static readonly string GetChildItem = "GetChildItem"; 22 | internal static readonly string GetContent = "GetContent"; 23 | internal static readonly string SetContent = "SetContent"; 24 | internal static readonly string ScriptBlockWithParam1 = "[CmdletBinding()] param([object]$object) $object.{0}()"; 25 | internal static readonly string ScriptBlockWithParam2 = "[CmdletBinding()] param([object]$object, [string]$p0) $object.{0}($p0)"; 26 | internal static readonly string ScriptBlockWithParam3 = "[CmdletBinding()] param([object]$object, [string]$p0, [string]$p1) $object.{0}($p0, $p1)"; 27 | 28 | 29 | internal static string[] DefinedCommands = { 30 | "Set-Location", 31 | "Get-Location", 32 | "Pop-Location", 33 | "Push-Location", 34 | "Get-ChildItem", 35 | "Resolve-Path", 36 | "Get-Item", 37 | "Test-Path", 38 | "Get-Content", 39 | "Set-Content", 40 | // Below are NotSupported commands, but we do handle their error messages. 41 | "Clear-Content", 42 | "Move-Item", 43 | "Copy-Item", 44 | "New-Item", 45 | "Remove-Item", 46 | "Rename-Item", 47 | "Clear-Item", 48 | "Set-Item", 49 | "Invoke-Item" 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Processors/PathResolverBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Linq; 27 | using System.Text; 28 | using System.Text.RegularExpressions; 29 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 30 | using CodeOwls.PowerShell.Provider.PathNodes; 31 | 32 | namespace CodeOwls.PowerShell.Paths.Processors 33 | { 34 | public abstract class PathResolverBase : IPathResolver 35 | { 36 | protected abstract IPathNode Root { get; } 37 | 38 | public virtual IEnumerable ResolvePath(IProviderContext providerContext, string path) 39 | { 40 | Regex re = new Regex(@"^[-_a-z0-9:]+:/?"); 41 | path = path.ToLowerInvariant().Replace('\\', '/'); 42 | path = re.Replace(path, ""); 43 | 44 | var factory = Root; 45 | 46 | var nodeMonikers = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); 47 | 48 | IEnumerable factories = new[] {factory}; 49 | 50 | foreach (var nodeMoniker in nodeMonikers ) 51 | { 52 | factories = factory.Resolve(providerContext, nodeMoniker); 53 | if (null == factories || !factories.Any()) 54 | { 55 | return null; 56 | } 57 | 58 | factory = factories.First(); 59 | } 60 | 61 | return factories; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /test/Azure.Network/Azure.Network.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | $driveName = 'AzureNetwork' 3 | Remove-PSDrive $driveName -ErrorAction SilentlyContinue 4 | Import-Module .\Azure.Network.psd1 -Force 5 | New-PSDrive -Name $driveName -PSProvider SHiPS -Root Azure.Network#Network 6 | cd $driveName":" 7 | #> 8 | 9 | using namespace Microsoft.PowerShell.SHiPS 10 | 11 | class Network : SHiPSDirectory 12 | { 13 | Network () 14 | { 15 | $this.Name = $this.GetType().Name; 16 | } 17 | 18 | Network ([string]$name) : base([string]$name) 19 | { 20 | $this.Name = $name; 21 | } 22 | 23 | [object[]] GetChildItem() 24 | { 25 | $result = @() 26 | $result += [NetworkInterfaces]::new() 27 | $result += [NetworkSecurityGroups]::new() 28 | $result += [VirtualNetworks]::new() 29 | return $result 30 | } 31 | 32 | static [void] WebRedirectMessage([string]$webUri, [string]$area) 33 | { 34 | Write-Verbose -Verbose "No items found. Please visit $webUri to learn more about $area" 35 | } 36 | } 37 | 38 | class NetworkLeaf : SHiPSLeaf 39 | { 40 | static [void] WebRedirectMessage([string]$webUri, [string]$area) 41 | { 42 | Write-Verbose -Verbose "No items found. Please visit $webUri to learn more about $area" 43 | } 44 | } 45 | 46 | class NetworkInterfaces : Network 47 | { 48 | 49 | NetworkInterfaces () : base ($this.GetType().Name) 50 | { 51 | } 52 | 53 | [object[]] GetChildItem() 54 | { 55 | $result = Get-AzureRmResourceGroup | ForEach-Object {AzureRM.Network\Get-AzureRmNetworkInterface -ResourceGroupName $_.ResourceGroupName} 56 | 57 | if(-not $result){ 58 | [NetworkLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/#pivot=services&panel=network','NetworkInterfaces') 59 | } 60 | 61 | return $result 62 | } 63 | } 64 | 65 | class NetworkSecurityGroups : Network 66 | { 67 | NetworkSecurityGroups () : base ($this.GetType().Name) 68 | { 69 | } 70 | 71 | [object[]] GetChildItem() 72 | { 73 | $result = AzureRM.Network\Get-AzureRmNetworkSecurityGroup 74 | 75 | if(-not $result){ 76 | [NetworkLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/#pivot=services&panel=network','NetworkSecurityGroup') 77 | } 78 | 79 | return $result 80 | } 81 | } 82 | 83 | class VirtualNetworks : Network 84 | { 85 | VirtualNetworks () : base ($this.GetType().Name) 86 | { 87 | } 88 | 89 | [object[]] GetChildItem() 90 | { 91 | $result = AzureRM.Network\Get-AzureRmVirtualNetwork 92 | 93 | if(-not $result){ 94 | [NetworkLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/#pivot=services&panel=network','VirtualNetwork') 95 | } 96 | 97 | return $result 98 | } 99 | } -------------------------------------------------------------------------------- /test/Azure.Compute/Azure.Compute.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | $driveName = 'azCompute' 3 | Remove-PSDrive $driveName -ErrorAction SilentlyContinue 4 | ipmo .\Azure.Compute.psd1 -Force 5 | new-psdrive -Name $driveName -PSProvider SHiPS -Root Azure.Compute#Compute 6 | cd $driveName":" 7 | #> 8 | using namespace Microsoft.PowerShell.SHiPS 9 | 10 | class Compute : SHiPSDirectory 11 | { 12 | Compute () 13 | { 14 | $this.Name = $this.GetType().Name; 15 | } 16 | 17 | Compute ([string]$name) 18 | { 19 | $this.Name = $name; 20 | } 21 | 22 | [object[]] GetChildItem() 23 | { 24 | $result = @() 25 | $result += [AvailabilitySets]::new() 26 | $result += [Locations]::new() 27 | $result += [VirtualMachines]::new() 28 | $result += [VirtualMachineScaleSets]::new() 29 | return $result 30 | } 31 | } 32 | 33 | class ComputeLeaf : SHiPSLeaf 34 | { 35 | static [void] WebRedirectMessage([string]$webUri, [string]$area) 36 | { 37 | Write-Verbose -Verbose "No items found. Please visit $webUri to learn more about $area" 38 | } 39 | } 40 | 41 | #TODO: What's the story for Disks, Images, Operations, RestorePointCollections,Snapshots 42 | 43 | class AvailabilitySets : Compute 44 | { 45 | [object[]] GetChildItem() 46 | { 47 | $result = Get-AzureRmResourceGroup | ForEach-Object {AzureRM.Compute\Get-AzureRmAvailabilitySet -ResourceGroupName $_.ResourceGroupName} 48 | 49 | if(-not $result){ 50 | [ComputeLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/virtual-machines/virtual-machines-windows-classic-configure-availability','AvailabilitySets') 51 | } 52 | 53 | return $result 54 | } 55 | } 56 | 57 | class Locations : Compute 58 | { 59 | [object[]] GetChildItem() 60 | { 61 | $result = AzureRM.Resources\Get-AzureRmLocation 62 | 63 | if(-not $result){ 64 | [ComputeLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/#pivot=services&panel=Compute','Locations') 65 | } 66 | 67 | return $result 68 | } 69 | } 70 | 71 | class VirtualMachines : Compute 72 | { 73 | [object[]] GetChildItem() 74 | { 75 | $result = AzureRM.Compute\Get-AzureRmVM 76 | 77 | if(-not $result){ 78 | [ComputeLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/virtual-machines','VirtualMachines') 79 | } 80 | 81 | return $result 82 | } 83 | } 84 | 85 | class VirtualMachineScaleSets : Compute 86 | { 87 | [object[]] GetChildItem() 88 | { 89 | $result = AzureRM.Compute\Get-AzureRmVmss 90 | 91 | if(-not $result){ 92 | [ComputeLeaf]::WebRedirectMessage('https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/','VirtualMachineScaleSets') 93 | } 94 | 95 | return $result 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Modules/SHiPS.formats.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SHiPS-GroupingFormat 6 | 7 | 8 | 9 | 10 | 11 | 4 12 | 13 | Directory: 14 | 15 | $drv = $_.PSDRIVE; $_.PSPARENTPATH -replace ".*#" -replace "^.[^\\/]*","${drv}:" 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | CollectionChildren 30 | 31 | Microsoft.PowerShell.SHiPS.SHiPSDirectory 32 | Microsoft.PowerShell.SHiPS.SHiPSLeaf 33 | 34 | 35 | PSParentPath 36 | SHiPS-GroupingFormat 37 | 38 | 39 | 40 | 41 | 5 42 | 43 | Left 44 | 45 | 46 | 40 47 | 48 | Left 49 | 50 | 51 | 52 | 53 | 54 | 55 | SSItemMode 56 | 57 | 58 | PSChildName 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/LeafNodeService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Management.Automation.Provider; 5 | using CodeOwls.PowerShell.Paths; 6 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 7 | using CodeOwls.PowerShell.Provider.PathNodes; 8 | 9 | namespace Microsoft.PowerShell.SHiPS 10 | { 11 | /// 12 | /// Defines actions that applies to a SHiPSLeaf node. 13 | /// 14 | internal class LeafNodeService : PathNodeBase, 15 | IGetItemContent, 16 | ISetItemContent, 17 | IClearItemContent 18 | { 19 | private readonly SHiPSLeaf _shipsLeaf; 20 | private static readonly string _leaf = "."; 21 | private readonly SHiPSDrive _drive; 22 | private readonly ContentHelper _contentHelper; 23 | 24 | internal LeafNodeService(object leafObject, SHiPSDrive drive, SHiPSDirectory parent) 25 | { 26 | _shipsLeaf = leafObject as SHiPSLeaf; 27 | _drive = drive; 28 | _contentHelper = new ContentHelper(_shipsLeaf, drive); 29 | if (_shipsLeaf != null) { _shipsLeaf.Parent = parent; } 30 | } 31 | 32 | public override IPathValue GetNodeValue() 33 | { 34 | return new LeafPathValue(_shipsLeaf, Name); 35 | } 36 | 37 | public override string ItemMode 38 | { 39 | get {return _leaf; } 40 | } 41 | 42 | public override string Name 43 | { 44 | get { return _shipsLeaf.Name; } 45 | } 46 | 47 | #region IGetItemContent 48 | 49 | public IContentReader GetContentReader(IProviderContext context) 50 | { 51 | return _contentHelper.GetContentReader(context); 52 | } 53 | 54 | public object GetContentReaderDynamicParameters(IProviderContext context) 55 | { 56 | return _contentHelper.GetContentReaderDynamicParameters(context); 57 | ; 58 | } 59 | 60 | #endregion 61 | 62 | #region ISetItemContent 63 | 64 | public IContentWriter GetContentWriter(IProviderContext context) 65 | { 66 | return _contentHelper.GetContentWriter(context); 67 | } 68 | 69 | public object GetContentWriterDynamicParameters(IProviderContext context) 70 | { 71 | return _contentHelper.GetContentWriterDynamicParameters(context); 72 | } 73 | 74 | #endregion 75 | 76 | #region IClearItemContent 77 | 78 | public void ClearContent(IProviderContext context) 79 | { 80 | // Define ClearContent for now as the PowerShell engine calls ClearContent first for Set-Content cmdlet. 81 | _contentHelper.ClearContent(context); 82 | } 83 | 84 | public object ClearContentDynamicParameters(IProviderContext context) 85 | { 86 | return _contentHelper.ClearContentDynamicParameters(context); 87 | } 88 | 89 | #endregion 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample3_TypeProvider/TypePathNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Management.Automation; 4 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 5 | using CodeOwls.PowerShell.Provider.PathNodes; 6 | 7 | namespace ProviderFramework_3_TypeProvider 8 | { 9 | class TypePathNode : PathNodeBase, IInvokeItem 10 | { 11 | #region unchanged code 12 | private readonly Type _type; 13 | 14 | public TypePathNode( Type type ) 15 | { 16 | _type = type; 17 | } 18 | 19 | public override IPathValue GetNodeValue() 20 | { 21 | return new LeafPathValue( _type, Name ); 22 | } 23 | 24 | public override string Name 25 | { 26 | get { return _type.FullName; } 27 | } 28 | #endregion 29 | 30 | /// 31 | /// returns an object defining custom parameters for the new-item cmdlet. 32 | /// 33 | /// because this provider requires a custom parameter for invoke-item, this 34 | /// implementation return an instance object describing those parameters 35 | /// 36 | public object InvokeItemParameters 37 | { 38 | get { return new CustomInvokeItemParameters(); } 39 | } 40 | 41 | public class CustomInvokeItemParameters 42 | { 43 | [Parameter( 44 | Mandatory = true, 45 | HelpMessage = "the name of the variable to hold the new instance")] 46 | public string VariableName {get; set; } 47 | } 48 | 49 | /// 50 | /// processes the invoke-item cmdlet when invoked on a path that 51 | /// resolves to a type value. 52 | /// 53 | /// this implementation attempts to create an instance of the type 54 | /// represented by the path. the type must have a default constructor 55 | /// for this to work. 56 | /// 57 | /// once an instance is created, it is stored in the variable indicated 58 | /// by the custom parameter 59 | /// 60 | /// the cmdlet providerContext, providing powershell and framework services 61 | /// the relative path to the item being invoked 62 | /// 63 | public IEnumerable InvokeItem(IProviderContext providerContext, string path) 64 | { 65 | // retrieve our custom parameter object 66 | var param = providerContext.DynamicParameters as CustomInvokeItemParameters; 67 | 68 | // create an instance of the type at this path value 69 | var item = Activator.CreateInstance(_type); 70 | 71 | // set the specified variable value to the created instance 72 | providerContext.SessionState.PSVariable.Set( param.VariableName, item ); 73 | 74 | // return the object created 75 | return new[] {item}; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Processors/PSProviderPathResolver.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | using System.Linq; 26 | using System.Management.Automation; 27 | using System.Text.RegularExpressions; 28 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 29 | using CodeOwls.PowerShell.Provider.PathNodes; 30 | 31 | namespace CodeOwls.PowerShell.Paths.Processors 32 | { 33 | public abstract class PSProviderPathResolver : PathResolverBase where T : PSDriveInfo 34 | { 35 | // psprovider path element (used to identify associated path drive) is identified 36 | // inside of []. for example: 37 | // dropbox\Dropbox::[123454321]\transcripts 38 | private static readonly Regex DriveIdentifierRegex = new Regex(@"^[^\[]*\[(.+)\]"); 39 | 40 | private readonly IEnumerable _drives; 41 | 42 | public T ActiveDrive { get; private set; } 43 | 44 | protected PSProviderPathResolver(IEnumerable drives) 45 | { 46 | if (null == drives) 47 | { 48 | throw new ArgumentNullException("drives"); 49 | } 50 | 51 | _drives = drives; 52 | } 53 | 54 | public override IEnumerable ResolvePath(IProviderContext providerContext, string path) 55 | { 56 | ActiveDrive = (T) _drives.First(); 57 | 58 | if (_drives.Any()) 59 | { 60 | var matches = DriveIdentifierRegex.Match(path); 61 | if (matches.Success) 62 | { 63 | var id = matches.Captures[0].Value; 64 | 65 | ActiveDrive = 66 | (T) _drives.First(d => StringComparer.OrdinalIgnoreCase.Equals(d.Root, id)); 67 | } 68 | } 69 | 70 | path = DriveIdentifierRegex.Replace(path, ""); 71 | 72 | var result = base.ResolvePath(providerContext, path); 73 | 74 | return result; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /samples/FamilyTree/FamilyTree.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Modeling a Family Tree for example: 3 | 4 | Austin 5 | - Bill 6 | - Ben 7 | - Cathy 8 | - Chris 9 | 10 | 11 | 12 | Assuming you have done git clone and run build.ps1, cd to your git clone folder and try the following. 13 | 14 | Import-Module SHiPS 15 | Import-Module .\samples\FamilyTree.psm1 16 | 17 | new-psdrive -name Austin -psprovider SHiPS -root FamilyTree#Austin 18 | cd Austin: 19 | dir 20 | cd Ben 21 | dir | %{$_.data} 22 | 23 | 24 | 25 | new-psdrive -name son -psprovider SHiPS -root FamilyTree#Ben 26 | cd son: 27 | dir 28 | dir | %{$_.data} 29 | 30 | #> 31 | 32 | using namespace Microsoft.PowerShell.SHiPS 33 | 34 | class Person 35 | { 36 | [string]$Name; 37 | [string]$DOB; 38 | [string]$Gender; 39 | 40 | Person([string]$name, [string]$dob, [string]$gender) 41 | { 42 | $this.Name = $name 43 | $this.DOB = $dob 44 | $this.Gender = $gender 45 | } 46 | } 47 | 48 | class Austin : SHiPSDirectory 49 | { 50 | Austin() : base($this.GetType()) 51 | { 52 | } 53 | 54 | # Optional method 55 | # Must define this c'tor if it can be used as a drive root, e.g. 56 | # new-psdrive -name abc -psprovider SHiPS -root module#type 57 | # Also it is good practice to define this c'tor so that you can create a drive and test it in isolation fashion. 58 | Austin([string]$name): base($name) 59 | { 60 | } 61 | 62 | # Mandatory it gets called by SHiPS while a user does 'dir' 63 | [object[]] GetChildItem() 64 | { 65 | $obj = @() 66 | 67 | Write-verbose "hello you have specified -verbose." 68 | 69 | $obj += [Ben]::new(); 70 | $obj += [Bill]::new(); 71 | 72 | return $obj; 73 | } 74 | } 75 | 76 | class Bill : SHiPSLeaf 77 | { 78 | static $PersonName = "Bill" 79 | static $PersonData =[Person]::new([Bill]::PersonName, "5015", "M"); 80 | 81 | Bill () : base ([Bill]::PersonName) 82 | { 83 | } 84 | } 85 | 86 | class Ben : SHiPSDirectory 87 | { 88 | static $PersonName = "Ben" 89 | static $PersonData =[Person]::new([Ben]::PersonName, "5005", "M"); 90 | 91 | Ben () : base ([Ben]::PersonName) 92 | { 93 | } 94 | 95 | Ben([string]$name): base($name) 96 | { 97 | } 98 | [object[]] GetChildItem() 99 | { 100 | $obj = @() 101 | $obj += [Chris]::new(); 102 | $obj += [Cathy]::new(); 103 | return $obj; 104 | } 105 | } 106 | 107 | 108 | class Chris : SHiPSLeaf 109 | { 110 | static $PersonName = "Chris" 111 | static $PersonData = [Person]::new([Chris]::PersonName, "5034", "M"); 112 | $Data = [Chris]::PersonData 113 | 114 | Chris () : base ([Chris]::PersonName) 115 | { 116 | } 117 | } 118 | 119 | class Cathy : SHiPSLeaf 120 | { 121 | static $PersonName = "Cathy" 122 | static $PersonData =[Person]::new([Cathy]::PersonName, "5050", "F"); 123 | $Data = [Cathy]::PersonData 124 | 125 | Cathy () : base ("Cathy") 126 | { 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /vs2015/SHiPS.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SHiPS", "SHiPS.csproj", "{EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {B352375B-7C58-4943-95C0-14871E17A208} = {B352375B-7C58-4943-95C0-14871E17A208} 9 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF} = {ED0453C7-C25A-4354-AC7A-046846D5E7FF} 10 | EndProjectSection 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOwls.PowerShell.Paths", "CodeOwls.PowerShell.Paths.csproj", "{ED0453C7-C25A-4354-AC7A-046846D5E7FF}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOwls.PowerShell.Provider", "CodeOwls.PowerShell.Provider.csproj", "{B352375B-7C58-4943-95C0-14871E17A208}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Debug|x86 = Debug|x86 20 | Release|Any CPU = Release|Any CPU 21 | Release|x86 = Release|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Debug|x86.Build.0 = Debug|Any CPU 28 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Release|x86.ActiveCfg = Release|Any CPU 31 | {EA5E0F26-2B66-4A65-A2D2-44FC36DC0D30}.Release|x86.Build.0 = Release|Any CPU 32 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Debug|x86.ActiveCfg = Debug|x86 35 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Debug|x86.Build.0 = Debug|x86 36 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Release|x86.ActiveCfg = Release|x86 39 | {ED0453C7-C25A-4354-AC7A-046846D5E7FF}.Release|x86.Build.0 = Release|x86 40 | {B352375B-7C58-4943-95C0-14871E17A208}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {B352375B-7C58-4943-95C0-14871E17A208}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {B352375B-7C58-4943-95C0-14871E17A208}.Debug|x86.ActiveCfg = Debug|x86 43 | {B352375B-7C58-4943-95C0-14871E17A208}.Debug|x86.Build.0 = Debug|x86 44 | {B352375B-7C58-4943-95C0-14871E17A208}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {B352375B-7C58-4943-95C0-14871E17A208}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {B352375B-7C58-4943-95C0-14871E17A208}.Release|x86.ActiveCfg = Release|x86 47 | {B352375B-7C58-4943-95C0-14871E17A208}.Release|x86.Build.0 = Release|x86 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /samples/FamilyTreeInCSharp/FamilyTreeInCSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8DCEE402-C9D8-4678-A901-27FC0962B63E} 8 | Library 9 | Properties 10 | FamilyTreeInCSharp 11 | FamilyTreeInCSharp 12 | v4.6.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\..\src\out\SHiPS\coreclr\Microsoft.PowerShell.SHiPS.dll 37 | 38 | 39 | 40 | 41 | packages\PowerShellStandard.Library.5.1.0-preview-04\lib\netstandard2.0\System.Management.Automation.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/Processors/IProviderContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Management.Automation; 27 | using System.Management.Automation.Provider; 28 | using System.Security.AccessControl; 29 | using CodeOwls.PowerShell.Paths.Processors; 30 | using CodeOwls.PowerShell.Provider.PathNodes; 31 | 32 | namespace CodeOwls.PowerShell.Provider.PathNodeProcessors 33 | { 34 | 35 | public interface IProviderContext 36 | { 37 | PSDriveInfo Drive { get; } 38 | string GetResourceString(string baseName, string resourceId); 39 | void ThrowTerminatingError(ErrorRecord errorRecord); 40 | bool ShouldProcess(string target); 41 | bool ShouldProcess(string target, string action); 42 | bool ShouldProcess(string verboseDescription, string verboseWarning, string caption); 43 | bool ShouldProcess(string verboseDescription, string verboseWarning, string caption, out ShouldProcessReason shouldProcessReason); 44 | bool ShouldContinue(string query, string caption); 45 | bool ShouldContinue(string query, string caption, ref bool yesToAll, ref bool noToAll); 46 | bool TransactionAvailable(); 47 | void WriteVerbose(string text); 48 | void WriteWarning(string text); 49 | void WriteProgress(ProgressRecord progressRecord); 50 | void WriteDebug(string text); 51 | void WriteItemObject(object item, string path, bool isContainer); 52 | void WritePropertyObject(object propertyValue, string path); 53 | void WriteSecurityDescriptorObject(ObjectSecurity securityDescriptor, string path); 54 | void WriteError(ErrorRecord errorRecord); 55 | bool Stopping { get; } 56 | IPathNode ResolvePath(string path); 57 | SessionState SessionState { get; } 58 | ProviderIntrinsics InvokeProvider { get; } 59 | CommandInvocationIntrinsics InvokeCommand { get; } 60 | PSCredential Credential { get; } 61 | bool Force { get; } 62 | bool Recurse { get; } 63 | bool ResolveFinalNodeFilterItems { get; } 64 | string Filter { get; } 65 | IEnumerable Include { get; } 66 | IEnumerable Exclude { get; } 67 | object DynamicParameters { get; } 68 | Version PathTopologyVersion { get; } 69 | string Path { get; } 70 | 71 | CmdletProvider CmdletProvider { get; } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /test/automation/abc.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Assuming you have done clone. Now cd to SHiPS\test\automation folder. Try the following. 3 | 4 | Import-Module ..\..\src\out\SHiPS\SHiPS 5 | Import-Module .\abc.psm1 6 | new-psdrive -name abc -psprovider SHiPS -root abc#abc 7 | cd abc: 8 | dir 9 | 10 | #> 11 | 12 | using namespace Microsoft.PowerShell.SHiPS 13 | $script:PowerShellProcessName = if($IsCoreCLR) {'pwsh'} else{ 'PowerShell'} 14 | 15 | class ABC : SHiPSDirectory 16 | { 17 | # Optional method 18 | # Must define this c'tor if it can be as a drive root, e.g. 19 | # new-psdrive -name abc -psprovider SHiPS -root abc#abc 20 | # Also it is good practice to define this c'tor so that you can test it in isolation fashion. 21 | ABC([string]$name): base($name) 22 | { 23 | } 24 | 25 | # Mandatory it gets called by PSMeteProvider while a user does 'dir' 26 | 27 | [object[]] GetChildItem() 28 | { 29 | #drawback: cannot be async as 'yield return' is not supported in class 30 | $obj = @() 31 | 32 | Write-verbose "You should see this verbose message without -verbose!!" -Verbose 33 | Write-warning "hello1 Warning!!" 34 | Write-debug "hello1 debuggggggggggggggggggggg!!" 35 | 36 | 37 | $bits= Get-Service BITS 38 | $ps=get-process $script:PowerShellProcessName 39 | 40 | Write-warning "hello2 Warning!!" 41 | 42 | $obj += [ABCLeaf]::new($bits.Name, $bits); 43 | 44 | Write-debug "hello2 debuggggggggggggggggggggg!!" 45 | 46 | $obj += [ABCLeaf]::new($ps.Name, $ps); 47 | $obj += get-process $script:PowerShellProcessName 48 | 49 | 50 | Write-verbose "hello2 you have used -verbose!!" 51 | 52 | return $obj; 53 | } 54 | 55 | <# 56 | 1. set-alias works only under a specific path. 57 | 2. dynamic parameters: 58 | 1) Cannot show cmdlet default possible values (e.g., AllUser, CurrentUser ) 59 | 2) Deal with parameterSets, 60 | 3) It will be tricky if New-Item and its corresponding command has conflict Parametersets? 61 | 4) Inability to hide/mark built-in parameters of provider cmdlets such as ItemType, Value, etc. 62 | #> 63 | [object]NewItem([string] $currentPath) 64 | { 65 | # need to know: 66 | # 1. dynamic parameters 67 | # 2. command 68 | 69 | $b = New-Object 'system.collections.generic.dictionary[string,hashtable]' 70 | $a=@{} 71 | if($currentPath -eq "VM") 72 | { 73 | $a = (gcm New-ModuleManifest).Parameters; 74 | $b.Add("New-AzureRmVM", $a) 75 | return $b 76 | } 77 | elseif($currentPath -eq "Image") 78 | { 79 | $b.Clear(); 80 | $a = (gcm New-AzureRmImage).Parameters; #you can do extra parameter process 81 | $b.Add("New-AzureRmImage", $a) 82 | return $b 83 | 84 | } 85 | else 86 | { 87 | $b.Clear(); 88 | $a = (gcm New-ModuleManifest).Parameters; 89 | $b.Add("New-ModuleManifest", $a) 90 | return $b 91 | #return $rootdefault 92 | } 93 | 94 | } 95 | } 96 | 97 | 98 | class ABCLeaf : SHiPSLeaf 99 | { 100 | [object]$Property = $null 101 | 102 | ABCLeaf([string]$name): base($name) 103 | { 104 | } 105 | 106 | # Optional method 107 | # This c'tor is used in yourself. But name parameter must exist. 108 | ABCLeaf ([string]$name, [object]$property) : base ($name) 109 | { 110 | $this.Property = $property 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample2_TypeProvider/TypeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Management.Automation; 6 | using System.Management.Automation.Provider; 7 | using System.Reflection; 8 | using System.Text; 9 | using CodeOwls.PowerShell.Paths.Processors; 10 | using CodeOwls.PowerShell.Provider; 11 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 12 | using CodeOwls.PowerShell.Provider.PathNodes; 13 | 14 | namespace ProviderFramework_2_TypeProvider 15 | { 16 | [CmdletProvider("Types", ProviderCapabilities.ShouldProcess )] 17 | public class TypeProvider : Provider 18 | { 19 | protected override IPathResolver PathResolver 20 | { 21 | get { return new PathResolver(); } 22 | } 23 | 24 | protected override System.Collections.ObjectModel.Collection InitializeDefaultDrives() 25 | { 26 | var driveInfo = new PSDriveInfo( "Types", ProviderInfo, String.Empty, "Provider for loaded .NET assemblies and types", null ); 27 | return new Collection{ new TypeDrive( driveInfo )}; 28 | } 29 | } 30 | 31 | public class TypeDrive : Drive 32 | { 33 | public TypeDrive(PSDriveInfo driveInfo) : base(driveInfo) 34 | { 35 | } 36 | } 37 | 38 | class PathResolver : PathResolverBase 39 | { 40 | protected override IPathNode Root 41 | { 42 | get { return new AppDomainPathNode(); } 43 | } 44 | } 45 | 46 | class AppDomainPathNode : PathNodeBase 47 | { 48 | public override IPathValue GetNodeValue() 49 | { 50 | return new ContainerPathValue( AppDomain.CurrentDomain, Name ); 51 | } 52 | 53 | public override string Name 54 | { 55 | get { return "AppDomain"; } 56 | } 57 | 58 | public override IEnumerable GetNodeChildren(CodeOwls.PowerShell.Provider.PathNodeProcessors.IProviderContext providerContext) 59 | { 60 | return from assembly in AppDomain.CurrentDomain.GetAssemblies() 61 | select new AssemblyPathNode(assembly) as IPathNode; 62 | } 63 | } 64 | 65 | class AssemblyPathNode : PathNodeBase 66 | { 67 | private readonly Assembly _assembly; 68 | 69 | public AssemblyPathNode( Assembly assembly ) 70 | { 71 | _assembly = assembly; 72 | } 73 | 74 | public override IPathValue GetNodeValue() 75 | { 76 | return new ContainerPathValue( _assembly, Name ); 77 | } 78 | 79 | public override string Name 80 | { 81 | get { return _assembly.GetName().Name; } 82 | } 83 | 84 | public override IEnumerable GetNodeChildren(CodeOwls.PowerShell.Provider.PathNodeProcessors.IProviderContext providerContext) 85 | { 86 | return from type in _assembly.GetExportedTypes() 87 | select new TypePathNode(type) as IPathNode; 88 | } 89 | } 90 | 91 | class TypePathNode : PathNodeBase 92 | { 93 | private readonly Type _type; 94 | 95 | public TypePathNode( Type type ) 96 | { 97 | _type = type; 98 | } 99 | 100 | public override IPathValue GetNodeValue() 101 | { 102 | return new LeafPathValue( _type, Name ); 103 | } 104 | 105 | public override string Name 106 | { 107 | get { return _type.FullName; } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample2_TypeProvider/P2F_Sample2_TypeProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {85439FAE-BEC1-4547-BBC0-F7D726830EAA} 9 | Library 10 | Properties 11 | P2F_Sample2_TypeProvider 12 | TypeProvider 13 | v4.7.1 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | 39 | 40 | ..\..\packages\PowerShellStandard.Library.5.1.0-preview-04\lib\netstandard2.0\System.Management.Automation.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {ed0453c7-c25a-4354-ac7a-046846d5e7ff} 57 | CodeOwls.PowerShell.Paths 58 | 59 | 60 | {b352375b-7c58-4943-95c0-14871e17a208} 61 | CodeOwls.PowerShell.Provider 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /test/automation/sampleRecursion.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Assuming you have done clone. Now cd to SHiPS\test\automation folder. Try the following. 3 | 4 | Import-Module ..\..\src\out\SHiPS\SHiPS 5 | Import-Module .\sampleRecursion.psm1 6 | 7 | new-psdrive -name JT -psprovider SHiPS -root sampleRecursion#Root 8 | 9 | cd JT: 10 | dir 11 | #> 12 | 13 | <# 14 | 15 | For debugging, you can do the following: 16 | 17 | Assuming you clone to E:\azure\ 18 | cd e:\azure\PSCloudConsole\test 19 | 20 | Import-Module .\SHiPS.psd1 21 | Import-Module .\sampleRecursion.psm1 22 | 23 | $mod=get-module 'sampleRecursion'; 24 | $t1=&($mod){[root]::new("root")} 25 | $a=$t1.GetChildItem() 26 | $a | %{$_.Name} 27 | 28 | $b=$a[0].GetChildItem() 29 | $b | %{$_.Name} 30 | 31 | #> 32 | 33 | 34 | using namespace Microsoft.PowerShell.SHiPS 35 | $script:PowerShellProcessName = if($IsCoreCLR) {'pwsh'} else{ 'PowerShell'} 36 | 37 | class DataHolder 38 | { 39 | [string] $Name 40 | [string[]]$ProcessName 41 | [int]$Number 42 | 43 | DataHolder(){} 44 | 45 | DataHolder ([string]$name, [string]$ProcessName, [int]$number) 46 | { 47 | $this.Name = $name; 48 | $this.ProcessName = $ProcessName; 49 | $this.Number = $number; 50 | } 51 | } 52 | 53 | 54 | class root: SHiPSDirectory 55 | { 56 | Root([string]$name): base($name) 57 | { 58 | } 59 | 60 | [object[]] GetChildItem() 61 | { 62 | return [Austin]::new("Austin", [DataHolder]::new("Process", $script:PowerShellProcessName, 1)); 63 | } 64 | } 65 | 66 | 67 | 68 | class Austin : SHiPSDirectory 69 | { 70 | Hidden [DataHolder]$data = $null 71 | [object]$Properties 72 | 73 | Austin ([string]$name, [object]$data) : base ($name) 74 | { 75 | $this.data=$data 76 | } 77 | 78 | 79 | [object[]] GetChildItem() 80 | { 81 | 82 | $n=$this.data.Number 83 | $m=$this.data.name 84 | Write-Verbose "$n, $m" 85 | 86 | if($this.data.Number -ge 5) 87 | { 88 | $n= $this.data.Number 89 | $message = "Current iteration number is $n. I have done enough. Exiting..." 90 | Write-Warning $message 91 | return $message 92 | } 93 | else 94 | { 95 | $this.Properties = (get-process $this.data.ProcessName); 96 | 97 | $next = [DataHolder]::New(); 98 | 99 | switch ($this.data.Number) 100 | { 101 | "1" { $next.ProcessName=$script:PowerShellProcessName; $next.Name ="explorer1"; $next.Number =2; break} 102 | "2" { $next.ProcessName=@($script:PowerShellProcessName); $next.Name ="explorer2"; $next.Number =3; break} 103 | "3" { $next.ProcessName=@($script:PowerShellProcessName); $next.Name ="explorer3"; $next.Number =4; break} 104 | "4" { $next.ProcessName=@($script:PowerShellProcessName); $next.Name ="explorer4"; $next.Number =5; break} 105 | "5" { $next.ProcessName=@($script:PowerShellProcessName); $next.Name ="explorer5"; $next.Number =6; break} 106 | } 107 | 108 | $n=$next.Number 109 | $m=$next.name 110 | 111 | Write-Verbose "$n, $m" 112 | 113 | if($this.data.Number -ge 5) 114 | { 115 | return [AlexLeaf]::new($($next.Name)) 116 | } 117 | else 118 | { 119 | return [Austin]::new($($next.Name), $next) 120 | } 121 | return $child; 122 | } 123 | 124 | } 125 | 126 | } 127 | 128 | class AlexLeaf : SHiPSLeaf 129 | { 130 | AlexLeaf([string]$name): base($name) 131 | { 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /samples/ShowProgress/ShowProgress.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Assuming you have done git clone and run build.ps1, cd to your git clone folder and try the following. 3 | 4 | Import-Module SHiPS 5 | Import-Module .\samples\ShowProgress.psm1 6 | new-psdrive -name m -psprovider SHiPS -root ShowProgress#BuiltinProgress 7 | 8 | cd m: 9 | dir 10 | dir -verbose 11 | 12 | cd c:\ 13 | new-psdrive -name n -psprovider SHiPS -root ShowProgress#NoBuiltinProgress 14 | cd n: 15 | dir -verbose 16 | 17 | #> 18 | 19 | using namespace Microsoft.PowerShell.SHiPS 20 | 21 | 22 | [SHiPSProvider(UseCache=$true)] 23 | class BuiltinProgress : SHiPSDirectory 24 | { 25 | Hidden [object]$data = $null 26 | 27 | BuiltinProgress([string]$name): base($name) 28 | { 29 | } 30 | 31 | 32 | 33 | [object[]] GetChildItem() 34 | { 35 | $obj = @() 36 | 37 | Write-verbose "hello, you specified -verbose." -Verbose 38 | Write-warning "hello, this is the Warning information." 39 | Write-debug "hello, this is the debug information." 40 | 41 | $activityMessage ="This is a demo to show you how to use Write-Progress for long running operations" 42 | 43 | $count=1 44 | $id = 5 # random number 45 | $parentId = 1 # builtin progressid=1 46 | 47 | While($count -lt 3) 48 | { 49 | $count++ 50 | Write-Progress -Id $id -ParentId $parentId -Activity $activityMessage -PercentComplete $count 51 | 52 | Start-Sleep -Seconds 1 53 | 54 | $ps=get-process powershell | Select-Object -First 1 55 | 56 | Write-warning "hello$count Warning info" 57 | 58 | Write-debug "hello$count debug info" 59 | 60 | $obj += [ABCLeaf]::new($ps.Name + $count, $ps); 61 | 62 | Write-verbose "hello$count verbose info" 63 | } 64 | 65 | Write-Progress -Id $id -ParentId $parentId -Activity $activityMessage -Completed 66 | 67 | return $obj; 68 | } 69 | } 70 | 71 | 72 | [SHiPSProvider(BuiltinProgress= $false)] 73 | class NoBuiltinProgress : SHiPSDirectory 74 | { 75 | Hidden [object]$data = $null 76 | 77 | NoBuiltinProgress([string]$name): base($name) 78 | { 79 | } 80 | 81 | 82 | 83 | [object[]] GetChildItem() 84 | { 85 | $obj = @() 86 | 87 | Write-verbose "hello, you specified -verbose." 88 | Write-warning "hello, this is the Warning information." 89 | Write-debug "hello, this is the debug information." 90 | 91 | $activityMessage ="This is a demo to show you how to use Write-Progress for long running operations" 92 | 93 | $count=1 94 | $id = 50 # random number 95 | $parentId = 1 # random number 96 | 97 | While($count -lt 3) 98 | { 99 | $count++ 100 | Write-Progress -Id $id -Activity $activityMessage -PercentComplete $count -ParentId $parentId 101 | 102 | Start-Sleep -Seconds 1 103 | 104 | $ps=get-process powershell | Select-Object -First 1 105 | 106 | Write-warning "hello$count Warning info" 107 | 108 | Write-debug "hello$count debug info" 109 | 110 | $obj += [ABCLeaf]::new($ps.Name + $count, $ps); 111 | 112 | Write-verbose "hello$count verbose info" 113 | } 114 | 115 | Write-Progress -Id $id -Activity $activityMessage -Completed 116 | 117 | return $obj; 118 | } 119 | } 120 | 121 | class ABCLeaf : SHiPSLeaf 122 | { 123 | Hidden [object]$data = $null 124 | 125 | 126 | ABCLeaf ([string]$name, [object]$data) : base ($name) 127 | { 128 | $this.data = $data 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.SHiPS/Node/SHiPSBase.cs: -------------------------------------------------------------------------------- 1 | using CodeOwls.PowerShell.Paths.Extensions; 2 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 3 | 4 | namespace Microsoft.PowerShell.SHiPS 5 | { 6 | /// 7 | /// Defines a base type for node objects. 8 | /// 9 | public abstract class SHiPSBase 10 | { 11 | internal static bool UseCacheDefaultValue = false; 12 | internal static bool BuiltinProgressDefaultValue = true; 13 | internal readonly ProviderContext SHiPSProviderContext = new ProviderContext(); 14 | private bool? _builtinProgress = null; 15 | private bool? _useCache = null; 16 | 17 | /// 18 | /// Default C'tor. 19 | /// 20 | protected SHiPSBase() : this(null) 21 | { 22 | } 23 | 24 | /// 25 | /// C'tor. 26 | /// 27 | /// Name of the node. 28 | protected SHiPSBase(string name) : this (name, isLeaf:false) 29 | { 30 | } 31 | 32 | /// 33 | /// C'tor. 34 | /// 35 | /// Name of the node. 36 | /// True if the node is a leaf node; false, the node has child items. 37 | protected SHiPSBase(string name, bool isLeaf) 38 | { 39 | //When name contains slash, it breaks provider navigation or caching. 40 | //We changed it to '-' before caching it. Otherwise, we will get cache missing every time. 41 | 42 | Name = name.MakeSafeForPath(); 43 | IsLeaf = isLeaf; 44 | if (!isLeaf) 45 | { 46 | var pp = SHiPSAttributeHandler.GetSHiPSProperty(this.GetType()); 47 | if (pp != null) 48 | { 49 | UseCache = pp.UseCache; 50 | BuiltinProgress = pp.BuiltinProgress; 51 | } 52 | } 53 | } 54 | 55 | /// 56 | /// Name of a node. 57 | /// 58 | public string Name { get; set; } 59 | 60 | /// 61 | /// A subset of context data from its base provider, i.e., CmdletProvider. 62 | /// The context under which the cmdlet is being called. 63 | /// 64 | protected ProviderContext ProviderContext 65 | { 66 | get { return SHiPSProviderContext; } 67 | } 68 | 69 | #region Internal Properties 70 | 71 | /// 72 | /// True if the node is a leaf node. 73 | /// 74 | internal bool IsLeaf { get; set; } 75 | 76 | /// 77 | /// True, data from Get-ChildItem call will be cached. False otherwise. 78 | /// By default, UseCache is set to false. 79 | /// 80 | internal bool UseCache 81 | { 82 | get 83 | { 84 | return _useCache ?? UseCacheDefaultValue; 85 | } 86 | set { _useCache = value; } 87 | } 88 | 89 | /// 90 | /// True SHiPS will call Write-Progress. False otherwise. 91 | /// By default BuiltinProgress is set to true. 92 | /// 93 | internal bool BuiltinProgress 94 | { 95 | get 96 | { 97 | return _builtinProgress ?? BuiltinProgressDefaultValue; 98 | } 99 | set { _builtinProgress = value; } 100 | } 101 | 102 | /// 103 | /// Parent node 104 | /// 105 | internal SHiPSDirectory Parent { get; set; } 106 | 107 | #endregion 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample1_NullProvider/P2F_Sample1_NullProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {E9CBC2B9-98B3-48AE-A5B5-7CBD9A154E78} 9 | Library 10 | Properties 11 | P2F_Sample1_NullProvider 12 | NullProvider 13 | v4.7.1 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | 39 | 40 | ..\..\packages\PowerShellStandard.Library.5.1.0-preview-04\lib\netstandard2.0\System.Management.Automation.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {ed0453c7-c25a-4354-ac7a-046846d5e7ff} 61 | CodeOwls.PowerShell.Paths 62 | 63 | 64 | {b352375b-7c58-4943-95c0-14871e17a208} 65 | CodeOwls.PowerShell.Provider 66 | 67 | 68 | 69 | 70 | 71 | 72 | 79 | -------------------------------------------------------------------------------- /test/automation/ctor.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Import-Module E:\azure\PSCloudConsole\test\ctor.psm1 -force 3 | $mod=get-module ctor 4 | &($mod){[Austin]::new('hello')} 5 | 6 | 7 | Import-Module ..\SHiPS.psd1 8 | Import-Module .\ctor.psm1 9 | new-psdrive -name cc -psprovider SHiPS -root ctor#Austin 10 | cd cc: 11 | dir 12 | 13 | #> 14 | 15 | using namespace Microsoft.PowerShell.SHiPS 16 | $script:PowerShellProcessName = if($IsCoreCLR) {'pwsh'} else{ 'PowerShell'} 17 | 18 | 19 | # collision with .Net - should work 20 | class Environment : SHiPSDirectory 21 | { 22 | 23 | Environment() 24 | { 25 | $this.Name = $this.GetType() 26 | } 27 | 28 | Environment([string]$name) 29 | { 30 | $this.Name = $name 31 | } 32 | 33 | 34 | [object[]] GetChildItem() 35 | { 36 | return [Environment]::new() 37 | } 38 | } 39 | 40 | 41 | class RegularClass 42 | { 43 | 44 | RegularClass() 45 | { 46 | 47 | } 48 | RegularClass([string]$name) 49 | { 50 | } 51 | 52 | 53 | [object[]] GetChildItem() 54 | { 55 | return [Belly]::new() 56 | } 57 | } 58 | 59 | 60 | class ClassWithNoRootNameCtor : SHiPSDirectory 61 | { 62 | 63 | ClassWithNoRootNameCtor() 64 | { 65 | 66 | } 67 | 68 | [object[]] GetChildItem() 69 | { 70 | return [Belly]::new() 71 | } 72 | } 73 | 74 | class ClassWithEmptyRootName : SHiPSDirectory 75 | { 76 | 77 | ClassWithEmptyRootName() 78 | { 79 | 80 | } 81 | 82 | ClassWithEmptyRootName([string]$name) 83 | { 84 | $this.Name = "" 85 | } 86 | [object[]] GetChildItem() 87 | { 88 | return [Belly]::new() 89 | } 90 | } 91 | 92 | class ClassWithNoneRootNodeType : SHiPSDirectory 93 | { 94 | 95 | ClassWithNoneRootNodeType() 96 | { 97 | 98 | } 99 | 100 | ClassWithNoneRootNodeType([string]$name) 101 | { 102 | $this.Name = $name 103 | } 104 | [object[]] GetChildItem() 105 | { 106 | return [Belly]::new() 107 | } 108 | } 109 | 110 | class ClassWithWrongNodeType : SHiPSDirectory 111 | { 112 | 113 | ClassWithWrongNodeType() 114 | { 115 | 116 | } 117 | 118 | ClassWithWrongNodeType([string]$name) 119 | { 120 | $this.Name = $name 121 | } 122 | [object[]] GetChildItem() 123 | { 124 | return [Belly]::new() 125 | } 126 | } 127 | 128 | class ClassWithNullName : SHiPSDirectory 129 | { 130 | 131 | ClassWithNullName() 132 | { 133 | #$this.Name = "test" 134 | } 135 | 136 | ClassWithNullName([string]$name) 137 | { 138 | $this.Name = $name 139 | } 140 | [object[]] GetChildItem() 141 | { 142 | return [ChildClassWithNullName]::new() 143 | } 144 | } 145 | 146 | class ChildClassWithNullName : ClassWithNullName 147 | { 148 | [object[]] GetChildItem() 149 | { 150 | write-Warning("hello world") 151 | return get-process $script:PowerShellProcessName 152 | } 153 | } 154 | 155 | class ClassInheritsFromShipsLeaf : SHiPSLeaf 156 | { 157 | 158 | ClassInheritsFromShipsLeaf() 159 | { 160 | $this.Name = "test" 161 | } 162 | 163 | ClassInheritsFromShipsLeaf([string]$name) 164 | { 165 | $this.Name = $name 166 | } 167 | [object[]] GetChildItem() 168 | { 169 | return [ClassInheritsFromShipsLeaf]::new() 170 | } 171 | } 172 | 173 | 174 | class Austin : Microsoft.PowerShell.SHiPS.SHiPSDirectory 175 | { 176 | 177 | Austin() 178 | { 179 | $this.Name = $this.GetType() 180 | } 181 | Austin([string]$name) 182 | { 183 | $this.Name = $name 184 | } 185 | 186 | 187 | [object[]] GetChildItem() 188 | { 189 | #return [Belly]::new() 190 | return [Belly]::new("belly") 191 | } 192 | } 193 | 194 | 195 | class Belly :Austin 196 | { 197 | Belly([string]$name) : base($name) 198 | { 199 | } 200 | 201 | [object[]] GetChildItem() 202 | { 203 | write-Warninggg("hello world") 204 | return get-process $script:PowerShellProcessName 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/p2f/src/Samples/P2F_Sample3_TypeProvider/P2F_Sample3_TypeProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {96A2EE47-84F0-4315-858F-6003A099A135} 9 | Library 10 | Properties 11 | P2F_Sample3_TypeProvider 12 | TypeProvider 13 | v4.7.1 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | False 39 | ..\..\..\..\..\..\Windows\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\1.0.0.0__31bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll 40 | 41 | 42 | 43 | 44 | ..\..\packages\PowerShellStandard.Library.5.1.0-preview-04\lib\netstandard2.0\System.Management.Automation.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {ed0453c7-c25a-4354-ac7a-046846d5e7ff} 63 | CodeOwls.PowerShell.Paths 64 | 65 | 66 | {b352375b-7c58-4943-95c0-14871e17a208} 67 | CodeOwls.PowerShell.Provider 68 | 69 | 70 | 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Authoring a SHiPS-based PowerShell Provider 2 | 3 | ## Design Document 4 | 5 | - [SHiPS design details.][design] 6 | 7 | ## Public APIs, Parameters, etc. 8 | 9 | - [See SHiPS APIs, parameters, etc.][api] 10 | 11 | ## Step 1 - Model your system 12 | 13 | - Let's say I want to navigate the following tree: 14 | 15 | ```powershell 16 | Austin 17 | / \ 18 | Ben Bill 19 | / \ 20 | Cathy Chris 21 | ``` 22 | 23 | ## Step 2 - Add code to your editor 24 | 25 | - Open your favorite text editor, such as [VSCode][vscode] or PowerShell ISE 26 | - For each node in the above tree, we'll create a class for it. The sample code looks like below. 27 | - Copy the code to your editor 28 | - Save it. Say `MyProvider.psm1`. 29 | 30 | ```powershell 31 | using namespace Microsoft.PowerShell.SHiPS 32 | 33 | class Austin : SHiPSDirectory 34 | { 35 | Austin([string]$name): base($name) 36 | { 37 | } 38 | 39 | [object[]] GetChildItem() 40 | { 41 | $obj = @() 42 | $obj += [Ben]::new(); 43 | $obj += [Bill]::new(); 44 | return $obj; 45 | } 46 | } 47 | 48 | class Bill : SHiPSLeaf 49 | { 50 | Bill () : base ("Bill") 51 | { 52 | } 53 | } 54 | 55 | class Ben : SHiPSDirectory 56 | { 57 | Ben () : base ("Ben") 58 | { 59 | } 60 | 61 | [object[]] GetChildItem() 62 | { 63 | $obj = @() 64 | $obj += [Chris]::new(); 65 | $obj += [Cathy]::new(); 66 | return $obj; 67 | } 68 | } 69 | 70 | class Chris : SHiPSLeaf 71 | { 72 | Chris () : base ("Chris") 73 | { 74 | } 75 | } 76 | 77 | class Cathy : SHiPSLeaf 78 | { 79 | Cathy () : base ("Cathy") 80 | { 81 | } 82 | } 83 | 84 | ``` 85 | 86 | ## Step 3 - Use MyProvider.psm1 87 | 88 | - Import-Module SHiPS (See [Installing SHiPS][readme] for details) 89 | - Create a PSDrive 90 | 91 | ```powershell 92 | 93 | new-psdrive -name Austin -psprovider SHiPS -root MyProvider#Austin 94 | 95 | cd Austin: 96 | PS Austin:\> dir 97 | Container: Microsoft.PowerShell.SHiPS\SHiPS::tt#Austin 98 | 99 | Mode Name 100 | ---- ---- 101 | + Ben 102 | . Bill 103 | 104 | ``` 105 | 106 | ## Key takeaways from this example 107 | 108 | - As MyProvider is built on top of the SHiPS, we need to include the namespace at the beginning 109 | ```powerShell 110 | using namespace Microsoft.PowerShell.SHiPS 111 | ``` 112 | - Each class as a navigation node needs inherits from `SHiPSDirectory` for a directory type, i.e., node contains child items. 113 | - For leaf nodes, you can return any type. For the sake of output formatting, you may define a class inherits from `SHiPSLeaf`. 114 | 115 | - As a root node, you need to define a constructor with node name as a parameter. For example, 116 | 117 | ```powershell 118 | Austin([string]$name): base($name) 119 | 120 | ``` 121 | - To support Get-ChildItem or dir, you need to implement the below method in your class. 122 | 123 | ```powershell 124 | [object[]] GetChildItem() 125 | 126 | ``` 127 | - When you create a PSDrive, the supported format is "module#type", e.g., 128 | 129 | ```powershell 130 | 131 | new-psdrive -name Austin -psprovider SHiPS -root MyProvider#Austin 132 | ``` 133 | 134 | ## More Samples 135 | 136 | Wanna try more samples? Review the following: 137 | 138 | - [FamilyTree][ft] 139 | - [File System as a Recursion Example][fs] 140 | - [Show Progress, and Other Attributes][sp] 141 | - [Dynamic Parameters Example][ds] 142 | - [C# Based Class][csharp] 143 | - [Navigate Azure Resources][az] 144 | - [Navigate CIM Classes and Namespaces][cim] 145 | 146 | [vscode]: https://github.com/PowerShell/PowerShell/blob/master/docs/learning-powershell/using-vscode.md#editing-with-vs-code 147 | [readme]: ../README.md#Installing-SHiPS 148 | [ft]: ../samples/FamilyTree 149 | [fs]: ../samples/FileSystem 150 | [sp]: ../samples/ShowProgress 151 | [csharp]: ../samples/FamilyTreeInCSharp 152 | [ds]: ../samples/DynamicParameter 153 | [az]: https://github.com/PowerShell/AzurePSDrive 154 | [design]: ./Design.md 155 | [api]: ./PublicAPIsAndMore.md 156 | [cim]: https://github.com/PowerShell/CimPSDrive 157 | -------------------------------------------------------------------------------- /test/Azure.Network/Azure.Network.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'Azure.Network' 3 | # 4 | # Generated by: raghus 5 | # 6 | # Generated on: 3/3/2017 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = '.\Azure.Network.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '1.0' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = '0ef45548-0080-11e7-93ae-92361f002671' 22 | 23 | # Author of this module 24 | Author = 'raghus' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'Microsoft' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2017 raghus. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | # Description = '' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | # PowerShellVersion = '' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | RequiredModules = @("$PSScriptRoot\..\SHiPS.psd1") 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @() 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = '*' 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | CmdletsToExport = '*' 76 | 77 | # Variables to export from this module 78 | VariablesToExport = '*' 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | AliasesToExport = '*' 82 | 83 | # DSC Networks to export from this module 84 | # DscNetworksToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | # FileList = @() 91 | 92 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 93 | PrivateData = @{ 94 | 95 | PSData = @{ 96 | 97 | # Tags applied to this module. These help with module discovery in online galleries. 98 | # Tags = @() 99 | 100 | # A URL to the license for this module. 101 | # LicenseUri = '' 102 | 103 | # A URL to the main website for this project. 104 | # ProjectUri = '' 105 | 106 | # A URL to an icon representing this module. 107 | # IconUri = '' 108 | 109 | # ReleaseNotes of this module 110 | # ReleaseNotes = '' 111 | 112 | } # End of PSData hashtable 113 | 114 | } # End of PrivateData hashtable 115 | 116 | # HelpInfo URI of this module 117 | # HelpInfoURI = '' 118 | 119 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 120 | # DefaultCommandPrefix = '' 121 | 122 | } -------------------------------------------------------------------------------- /test/Azure.Compute/Azure.Compute.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'Azure.Compute' 3 | # 4 | # Generated by: hemantm 5 | # 6 | # Generated on: 3/3/2017 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = '.\Azure.Compute.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '1.0' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = '05b34008-4f52-478a-afb9-a6179526f754' 22 | 23 | # Author of this module 24 | Author = 'hemantm' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'Unknown' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2017 hemantm. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | # Description = '' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | # PowerShellVersion = '' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | RequiredModules = @("$PSScriptRoot\..\SHiPS.psd1") 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @() 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = '*' 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | CmdletsToExport = '*' 76 | 77 | # Variables to export from this module 78 | VariablesToExport = '*' 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | AliasesToExport = '*' 82 | 83 | # DSC resources to export from this module 84 | # DscResourcesToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | # FileList = @() 91 | 92 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 93 | PrivateData = @{ 94 | 95 | PSData = @{ 96 | 97 | # Tags applied to this module. These help with module discovery in online galleries. 98 | # Tags = @() 99 | 100 | # A URL to the license for this module. 101 | # LicenseUri = '' 102 | 103 | # A URL to the main website for this project. 104 | # ProjectUri = '' 105 | 106 | # A URL to an icon representing this module. 107 | # IconUri = '' 108 | 109 | # ReleaseNotes of this module 110 | # ReleaseNotes = '' 111 | 112 | } # End of PSData hashtable 113 | 114 | } # End of PrivateData hashtable 115 | 116 | # HelpInfo URI of this module 117 | # HelpInfoURI = '' 118 | 119 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 120 | # DefaultCommandPrefix = '' 121 | 122 | } 123 | -------------------------------------------------------------------------------- /docs/PublicAPIsAndMore.md: -------------------------------------------------------------------------------- 1 | # SHiPS Public APIs, Parameters, and More 2 | 3 | ## SHiPS Namespace - Microsoft.PowerShell.SHiPS 4 | 5 | You can follow the format below to reference SHiPS namespace. 6 | 7 | `PowerShell` 8 | 9 | ```powershell 10 | using namespace Microsoft.PowerShell.SHiPS 11 | ``` 12 | 13 | `C#` 14 | 15 | ``` C# 16 | using Microsoft.PowerShell.SHiPS 17 | ``` 18 | 19 | ## SHiPS Public Types 20 | 21 | - SHiPSDirectory 22 | 23 | A base class for defining a type that represents a node object which contains any child items. 24 | 25 | - SHiPSLeaf 26 | 27 | Defines a type that represents a leaf node. 28 | 29 | > NOTE: 30 | Above types have a constructor with one string parameter, which represents as a node name. 31 | The name is mandatory and must be unique under the same parent node - 'directory'. 32 | With that, in PowerShell, you can pass in a node name argument as follows. 33 | 34 | ```powershell 35 | Employee([string]$name) : base ($name) 36 | { 37 | } 38 | ``` 39 | 40 | ## Public APIs 41 | 42 | - [object[]] GetChildItem() 43 | 44 | Returns a list of objects while a user types `Get-ChildItem (or dir)` 45 | 46 | - [object] GetChildItemDynamicParameters() 47 | 48 | Defines Get-ChildItem dynamic parameters for `Get-ChildItem` 49 | 50 | - [object] SetContent([string]$content, [string]$path) 51 | Sets the content string text in $content to the path node specified in $path. 52 | 53 | - [string] GetContent() 54 | Gets the content text from the current node object. 55 | 56 | ## Public Attributes 57 | 58 | SHiPS contains the following attributes: 59 | 60 | - UseCache 61 | 62 | By default, SHiPS does not cache any child items in to memory. 63 | However for better navigation user experience like a situation where requires some time to retrieve data from remote data store, an author can decide to set UseCache to true to cache data returned from Get-ChildItem to memory in the current PowerShell session. 64 | The cache data will be deleted once the PowerShell session is closed. 65 | 66 | ```powershell 67 | [SHiPSProvider(UseCache=$true)] 68 | ``` 69 | 70 | To refresh data, a user can type `-force` 71 | 72 | - BuiltinProgress 73 | 74 | By default, SHiPS shows the progress. However an module author can decide to not enable the builtin progress by setting BuiltinProgress to false. 75 | 76 | ```powershell 77 | [SHiPSProvider(BuiltinProgress=$false)] 78 | ``` 79 | 80 | ## Public Parameters 81 | 82 | The following properties are exposed to SHiPS' derived classes as protected members. 83 | 84 | - `Name`: provider's node name 85 | 86 | As above mentioned, you can pass in the node name to base class such as 87 | 88 | ```powershell 89 | Compute([string]$name) : base ($name) 90 | { 91 | } 92 | ``` 93 | or 94 | 95 | ```powershell 96 | Compute ([string]$name) 97 | { 98 | $this.Name = $name; 99 | } 100 | ``` 101 | 102 | - `ProviderContext`: provider's data 103 | 104 | - `DynamicParameters` 105 | As above mentioned, an author can define dynamic parameters for their providers. 106 | To process whether a user uses these dyanmic parameters, author can access them via the following mechanism. 107 | 108 | ```powershell 109 | $this.ProviderContext.DynamicParameters 110 | ``` 111 | 112 | For more usages, see [dynamic parameters example][ds]. 113 | 114 | - `Filter` 115 | Gets the filter property that was supplied by a user. 116 | `-Filter` is a builtin parameter in the Get-ChildItem cmdlet. 117 | Considering there are times you may want to process a 'server-side' filtering for better user experience, SHiPS exposed Filter query string to the module. For example you can access it as follows: 118 | 119 | ```powershell 120 | $queryString = $this.ProviderContext.Filter 121 | ``` 122 | 123 | - `Recurse`: Gets the recurse property. 124 | It's possibly you want to perform filtering in your side server and instruct the server whether filtering recursively or not. In that you can check whether a user specifies -Recurse. 125 | 126 | ```powershell 127 | if(-not $this.ProviderContext.Recurse) 128 | ``` 129 | - `Force` Gets the force property. 130 | 131 | ```powershell 132 | if(-not $this.ProviderContext.Force) 133 | ``` 134 | 135 | [ds]:../samples/DynamicParameter 136 | -------------------------------------------------------------------------------- /src/p2f/src/CodeOwls.PowerShell/CodeOwls.PowerShell.Paths/PathNodeBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Code Owls LLC 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | 24 | 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Management.Automation.Runspaces; 29 | using CodeOwls.PowerShell.Paths.Processors; 30 | using CodeOwls.PowerShell.Provider.PathNodeProcessors; 31 | 32 | namespace CodeOwls.PowerShell.Provider.PathNodes 33 | { 34 | public abstract class PathNodeBase : IPathNode 35 | { 36 | public virtual IEnumerable Resolve(IProviderContext providerContext, string nodeName) 37 | { 38 | var children = GetNodeChildren( providerContext ); 39 | if (children != null) 40 | { 41 | foreach (var child in children) 42 | { 43 | if (null == nodeName || StringComparer.OrdinalIgnoreCase.Equals(nodeName, child.Name)) 44 | { 45 | yield return child; 46 | } 47 | } 48 | } 49 | } 50 | 51 | public abstract IPathValue GetNodeValue(); 52 | public virtual object GetNodeChildrenParameters { get { return null; } } 53 | public virtual IEnumerable GetNodeChildren(IProviderContext providerContext) 54 | { 55 | return null; 56 | } 57 | 58 | static readonly Dictionary ItemModeCache = new Dictionary(); 59 | protected string EncodedItemMode 60 | { 61 | get 62 | { 63 | // "dnrgslcmri" 64 | // "d+~<>0cmri" 65 | 66 | bool canCopy = null != this as ICopyItem; 67 | bool canRemove = null != this as IRemoveItem; 68 | bool canMove = canCopy && canRemove; 69 | var d = " "; 70 | var containerEncoded = GetNodeValue().IsCollection ? "d" : d; 71 | var newEncoded = null != this as INewItem ? "+" : d; 72 | var removeEncoded = null != this as IRemoveItem ? "~" : d; 73 | 74 | var getEncoded = null != GetNodeValue() ? "<" : d; 75 | var setEncoded = null != this as ISetItem ? ">" : d; 76 | var clearEncoded = null != this as IClearItem ? "0" : d; 77 | 78 | var copyEncoded = canCopy ? "c" : d; 79 | var moveEncoded = canMove ? "m" : d; ; 80 | var renameEncoded = null != this as IRenameItem ? "r" : d; 81 | var invokeEncoded = null != this as IInvokeItem ? "i" : d; 82 | return containerEncoded + newEncoded + removeEncoded + getEncoded + setEncoded + 83 | clearEncoded + 84 | copyEncoded + moveEncoded + renameEncoded + invokeEncoded; 85 | } 86 | } 87 | public virtual string ItemMode 88 | { 89 | get 90 | { 91 | var type = GetType(); 92 | 93 | if (!ItemModeCache.ContainsKey(type)) 94 | { 95 | ItemModeCache[type] = EncodedItemMode; 96 | } 97 | 98 | return ItemModeCache[type]; 99 | } 100 | } 101 | 102 | public abstract string Name 103 | { 104 | get; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tools/download.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Let's quit on interrupt of subcommands 4 | trap ' 5 | trap - INT # restore default INT handler 6 | echo "Interrupted" 7 | kill -s INT "$$" 8 | ' INT 9 | 10 | get_url() { 11 | release=v6.0.0-beta.5 12 | echo "https://github.com/PowerShell/PowerShell/releases/download/$release/$1" 13 | } 14 | 15 | # Get OS specific asset ID and package name 16 | case "$OSTYPE" in 17 | linux*) 18 | source /etc/os-release 19 | # Install curl and wget to download package 20 | case "$ID" in 21 | centos*) 22 | if ! hash curl 2>/dev/null; then 23 | echo "curl not found, installing..." 24 | sudo yum install -y curl 25 | fi 26 | 27 | package=powershell-6.0.0_beta.5.el7.centos.x86_64.rpm 28 | ;; 29 | ubuntu) 30 | if ! hash curl 2>/dev/null; then 31 | echo "curl not found, installing..." 32 | sudo apt-get install -y curl 33 | fi 34 | 35 | case "$VERSION_ID" in 36 | 14.04) 37 | package=powershell_6.0.0-beta.5-1ubuntu1.14.04.1_amd64.deb 38 | ;; 39 | 16.04) 40 | package=powershell_6.0.0-beta.5-1ubuntu1.16.04.1_amd64.deb 41 | ;; 42 | *) 43 | echo "Ubuntu $VERSION_ID is not supported!" >&2 44 | exit 2 45 | esac 46 | ;; 47 | *) 48 | echo "$NAME is not supported!" >&2 49 | exit 2 50 | esac 51 | ;; 52 | darwin*) 53 | # We don't check for curl as macOS should have a system version 54 | package=powershell-6.0.0-beta.5-osx.10.12-x64.pkg 55 | ;; 56 | *) 57 | echo "$OSTYPE is not supported!" >&2 58 | exit 2 59 | ;; 60 | esac 61 | 62 | curl -L -o "$package" $(get_url "$package") 63 | 64 | if [[ ! -r "$package" ]]; then 65 | echo "ERROR: $package failed to download! Aborting..." >&2 66 | exit 1 67 | fi 68 | 69 | # Installs PowerShell package 70 | case "$OSTYPE" in 71 | linux*) 72 | source /etc/os-release 73 | # Install dependencies 74 | echo "Installing PowerShell with sudo..." 75 | case "$ID" in 76 | centos) 77 | # yum automatically resolves dependencies for local packages 78 | sudo yum install "./$package" 79 | ;; 80 | ubuntu) 81 | # dpkg does not automatically resolve dependencies, but spouts ugly errors 82 | sudo dpkg -i "./$package" &> /dev/null 83 | # Resolve dependencies 84 | sudo apt-get install -f 85 | ;; 86 | *) 87 | esac 88 | ;; 89 | darwin*) 90 | patched=0 91 | if hash brew 2>/dev/null; then 92 | if [[ ! -d $(brew --prefix openssl) ]]; then 93 | echo "Installing OpenSSL with brew..." 94 | if ! brew install openssl; then 95 | echo "ERROR: OpenSSL failed to install! Crypto functions will not work..." >&2 96 | # Don't abort because it is not fatal 97 | elif ! brew install curl --with-openssl; then 98 | echo "ERROR: curl failed to build against OpenSSL; SSL functions will not work..." >&2 99 | # Still not fatal 100 | else 101 | # OpenSSL installation succeeded; remember to patch System.Net.Http after PowerShell installation 102 | patched=1 103 | fi 104 | fi 105 | 106 | else 107 | echo "ERROR: brew not found! OpenSSL may not be available..." >&2 108 | # Don't abort because it is not fatal 109 | fi 110 | 111 | echo "Installing $package with sudo ..." 112 | sudo installer -pkg "./$package" -target / 113 | if [[ $patched -eq 1 ]]; then 114 | echo "Patching System.Net.Http for libcurl and OpenSSL..." 115 | find /usr/local/microsoft/powershell -name System.Net.Http.Native.dylib | xargs sudo install_name_tool -change /usr/lib/libcurl.4.dylib /usr/local/opt/curl/lib/libcurl.4.dylib 116 | fi 117 | ;; 118 | esac 119 | 120 | powershell -noprofile -c '"Congratulations! PowerShell is installed at $PSHOME"' 121 | success=$? 122 | 123 | if [[ "$success" != 0 ]]; then 124 | echo "ERROR: PowerShell failed to install!" >&2 125 | exit "$success" 126 | fi 127 | -------------------------------------------------------------------------------- /samples/Library/Library.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | Modeling a Music Tree for example: 3 | 4 | M: 5 | - Classic 6 | - SwanLack 7 | - BlueDanube 8 | - Rock 9 | - Turnstile, Generator 10 | -Imagine Dragons, Thunder 11 | 12 | 13 | 14 | Assuming you have run Install-Module SHiPS 15 | 16 | Import-Module SHiPS 17 | Import-Module .\samples\Library\Library.psm1 18 | 19 | new-psdrive -name M -psprovider SHiPS -root Library#Music 20 | cd M: 21 | dir 22 | Get-Content .\Classic\SwanLake 23 | Set-Content .\Classic\SwanLake -Value 'Cool!' 24 | Get-Content .\Classic\SwanLake 25 | #> 26 | 27 | using namespace Microsoft.PowerShell.SHiPS 28 | 29 | 30 | [SHiPSProvider(UseCache=$true)] 31 | class Music : SHiPSDirectory 32 | { 33 | # Must define this c'tor if it can be used as a drive root, e.g. 34 | # new-psdrive -name abc -psprovider SHiPS -root module#type 35 | # Also it is good practice to define this c'tor so that you can create a drive and test it in isolation fashion. 36 | Music([string]$name): base($name) 37 | { 38 | } 39 | 40 | # Mandatory it gets called by SHiPS while a user does 'dir' 41 | [object[]] GetChildItem() 42 | { 43 | $obj = @() 44 | $obj += [Classic]::new() 45 | $obj += [Rock]::new() 46 | 47 | return $obj; 48 | } 49 | } 50 | class Classic : SHiPSDirectory 51 | { 52 | # Mimicking file storage, database, store, etc 53 | hidden [object]$children = @() 54 | hidden static [string]$SwanLake = " 55 | Tchaikovsky's magical ballet tells the story of the doomed love of Prince Siegfried and Princess Odette, 56 | Prince Siegfried goes out hunting one night and chases a group of swans - one of them transforms into a 57 | young woman, Odette, who explains that she and her companions were turned into swans by the evil Baron Von Rothbart." 58 | 59 | hidden static [string]$Donau = " 60 | Johann Strauss Jr.'s status as an internationally recognized Austrian icon began with the success 61 | of his waltz, An der schönen, blauen Donau (The Blue Danube Waltz), at the Paris Exhibition of 1867." 62 | 63 | 64 | Classic() : base ($this.GetType()) 65 | { 66 | $this.children += [MusicLeaf]::new('SwanLake', [Classic]::SwanLake) 67 | $this.children += [MusicLeaf]::new('BlueDanube', [Classic]::Donau) 68 | } 69 | 70 | [object[]] GetChildItem() 71 | { 72 | # fetch data from our storage and return it 73 | return $this.children 74 | } 75 | 76 | # Directory supports SetContent and GetContent because the path may not exist yet, equivalent to new-item in this case. 77 | # Leaf supports GetContent only. 78 | [object] SetContent([string]$value, [string]$path) 79 | { 80 | # 'value' is the string content. We can save it to a file, database, upload it to Azure, etc. 81 | # But for an this example, we just store it into the memory. 82 | 83 | $newPath = Microsoft.PowerShell.Management\Split-Path $Path -Leaf 84 | $child = [MusicLeaf]::new($newPath, $value) 85 | $this.children +=$child 86 | return $child 87 | } 88 | } 89 | 90 | 91 | class MusicLeaf : SHiPSLeaf 92 | { 93 | hidden [string]$data = $null 94 | 95 | MusicLeaf([string]$name) : base ($name) 96 | { 97 | } 98 | 99 | MusicLeaf ([string]$name, [string]$content) : base ($name) 100 | { 101 | $this.data = $content 102 | } 103 | 104 | [string] GetContent() 105 | { 106 | $bp = $this.ProviderContext.BoundParameters 107 | 108 | if ($bp) 109 | { 110 | # Get-Content -TotalCount 111 | if ($bp.TotalCount) 112 | { 113 | # Making up lines artificially 114 | $text = @() 115 | $array = $this.data -split '\s+' -match '\S' 116 | $count = [Math]::Min($bp.TotalCount, $array.Length) 117 | for ($i = 0; $i -lt $count; $i++) { 118 | $text+=$array[$i] 119 | } 120 | return $text 121 | } 122 | } 123 | 124 | return $this.data 125 | } 126 | 127 | [object] SetContent([string]$value, [string]$path) 128 | { 129 | $this.data = $value 130 | return $this 131 | } 132 | } 133 | 134 | 135 | class Rock : SHiPSDirectory 136 | { 137 | Rock () : base ($this.GetType()) 138 | { 139 | } 140 | 141 | [object[]] GetChildItem() 142 | { 143 | $obj = @() 144 | $obj += "Turnstile, Generator" 145 | $obj += "Imagine Dragons, Thunder" 146 | 147 | return $obj 148 | } 149 | } 150 | --------------------------------------------------------------------------------