As I've been working on my new PowerShell project, which I've discussed over recent posts, I keep "discovering" fun scripting opportunities. Today I want to share some code I've come up with that makes it easier to build a PowerShell module directory structure. There are plenty of existing tools and scripts for scaffolding a project or directory structure. Projects like Plaster for example. I am by no means recommending my functions over these tools. But maybe they might fill a niche, spark an idea for your own work, or teach you something new about PowerShell.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The Model Module
I begin by creating a sample module directory folder. This is the folder layout that I am tending to use these days when writing a new PowerShell module. I'll also create a few simple text files like readme, changelog, and license files There's no need to create the module psm1 file or the manifest. That is a separate and specific task. What I'm defining now is a generic model.
By the way, Show-Tree is from the PSScriptTools module.
Exporting
The export process is relatively simple. I need to recurse through the folder listing directories and files. Because I might have nested directories, I need to capture the relative path.
In order to simplify the relative path, I need to set my location to the root directory. Because I know I will eventually be recreating this structure, I need to be able to distinguish between directories and files. I also need to capture the file contents.
Get-ChildItem -Recurse |
ForEach-Object {
$relPath = (Resolve-Path -Path $_.fullname -Relative) -replace "\.\\", ""
Write-Verbose "Processing $relPath"
if ($_.Gettype().name -eq 'FileInfo') {
$f = [pscustomobject]@{
ItemType = "file"
Path = $relPath
Content = (Get-Content -Path $_.fullname)
}
$out.add($f)
}
else {
$d = [pscustomobject]@{
ItemType = "directory"
Path = $relPath
}
$out.Add($d)
}
} #foreach-object
In my code, I'm stripping off the leading .\ to the relative path. I then create a custom object for each item type. Each object is added to the $out list. The list is then converted to json and saved to a file.
$out | ConvertTo-Json | Out-File -FilePath $FilePath
The command created this json content.
[
{
"Created": "12/16/2021 10:44 AM",
"CreatedBy": "Jeff",
"Computername": "THINKP1",
"Source": "C:\\work\\sample",
"Version": "1.0"
},
{
"ItemType": "directory",
"Path": ".github"
},
{
"ItemType": "directory",
"Path": ".vscode"
},
{
"ItemType": "directory",
"Path": "docs"
},
{
"ItemType": "directory",
"Path": "en-us"
},
{
"ItemType": "directory",
"Path": "formats"
},
{
"ItemType": "directory",
"Path": "functions"
},
{
"ItemType": "directory",
"Path": "icons"
},
{
"ItemType": "directory",
"Path": "images"
},
{
"ItemType": "directory",
"Path": "samples"
},
{
"ItemType": "directory",
"Path": "tests"
},
{
"ItemType": "directory",
"Path": "types"
},
{
"ItemType": "file",
"Path": "changelog.md",
"Content": {
"value": "# Changelog",
"PSPath": "C:\\work\\sample\\changelog.md",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "changelog.md",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": "License.txt",
"Content": [
{
"value": "MIT License",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 2
},
{
"value": "Copyright (c) 2021 JDH Information Technology Solutions, Inc.",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 3
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 4
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 5
},
{
"value": "Permission is hereby granted, free of charge, to any person obtaining a copy",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 6
},
{
"value": "of this software and associated documentation files (the \"Software\"), to deal",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 7
},
{
"value": "in the Software without restriction, including without limitation the rights",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 8
},
{
"value": "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 9
},
{
"value": "copies of the Software, and to permit persons to whom the Software is",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 10
},
{
"value": "furnished to do so, subject to the following conditions:",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 11
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 12
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 13
},
{
"value": "The above copyright notice and this permission notice shall be included in",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 14
},
{
"value": "all copies or substantial portions of the Software.",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 15
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 16
},
{
"value": "",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 17
},
{
"value": "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 18
},
{
"value": "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 19
},
{
"value": "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 20
},
{
"value": "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 21
},
{
"value": "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 22
},
{
"value": "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 23
},
{
"value": "THE SOFTWARE.",
"PSPath": "C:\\work\\sample\\License.txt",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "License.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 24
}
]
},
{
"ItemType": "file",
"Path": "README.md",
"Content": {
"value": "# README",
"PSPath": "C:\\work\\sample\\README.md",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "README.md",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": "scratch-changelog.md",
"Content": {
"value": "# scratch change",
"PSPath": "C:\\work\\sample\\scratch-changelog.md",
"PSParentPath": "C:\\work\\sample",
"PSChildName": "scratch-changelog.md",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": ".vscode\\tasks.json",
"Content": [
{
"value": "{",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
},
{
"value": " // See https://go.microsoft.com/fwlink/?LinkId=733558",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 2
},
{
"value": " // for the documentation about the tasks.json format",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 3
},
{
"value": " \"version\": \"2.0.0\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 4
},
{
"value": " \"tasks\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 5
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 6
},
{
"value": " \"label\": \"Pester Test\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 7
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 8
},
{
"value": " \"command\": \"Get-Module Pester | Remove-Module;import-module -FullyQualifiedName @{ModuleName=\u0027Pester\u0027;RequiredVersion=\u00274.10.1\u0027};Invoke-Pester -Script .\\\\tests\\\\*test*.ps1 -PesterOption @{IncludeVSCodeMarker=$true}\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 9
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 10
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 11
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 12
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 13
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 14
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 15
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 16
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 17
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 18
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 19
},
{
"value": " \"label\": \"Build markdown help files\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 20
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 21
},
{
"value": " \"command\": \"Import-Module $pwd\\\\*.psd1 -force;$module = Split-Path $pwd -leaf;New-MarkdownHelp -module $module -output $pwd\\\\docs -force\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 22
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 23
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 24
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 25
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 26
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 27
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 28
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 29
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 30
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 31
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 32
},
{
"value": " \"label\": \"Add markdown help file\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 33
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 34
},
{
"value": " \"command\": \"Import-Module $pwd\\\\*.psd1 -force;$module = Split-Path $pwd -leaf;$cmd = Read-Host \u0027What command needs help?\u0027;New-MarkdownHelp -command $cmd -output $pwd\\\\docs -force;code $pwd\\\\docs\\\\$cmd.md\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 35
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 36
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 37
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 38
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 39
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 40
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 41
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 42
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 43
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 44
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 45
},
{
"value": " \"label\": \"Update markdown help file\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 46
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 47
},
{
"value": " \"command\": \"Import-Module $pwd\\\\*.psd1 -force;$module = Split-Path $pwd -leaf;$cmd = Read-Host \u0027What command needs UPDATED help?\u0027;Update-MarkdownHelp -path $pwd\\\\docs\\\\$cmd.md -force;code $pwd\\\\docs\\\\$cmd.md\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 48
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 49
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 50
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 51
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 52
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 53
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 54
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 55
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 56
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 57
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 58
},
{
"value": " \"label\": \"Build PowerShell module external help\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 59
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 60
},
{
"value": " \"command\": \"c:\\\\scripts\\\\build-externalhelp.ps1\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 61
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 62
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 63
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 64
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 65
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 66
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 67
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 68
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 69
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 70
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 71
},
{
"value": " \"label\": \"Push release to GitHub WHATIF\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 72
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 73
},
{
"value": " \"command\": \"c:\\\\scripts\\\\GitReleasePush.ps1 -whatif\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 74
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 75
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 76
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 77
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 78
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 79
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 80
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 81
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 82
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 83
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 84
},
{
"value": " \"label\": \"Push PREVIEW release to GitHub\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 85
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 86
},
{
"value": " \"command\": \"c:\\\\scripts\\\\GitReleasePush.ps1 -PREVIEW\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 87
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 88
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 89
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 90
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 91
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 92
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 93
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 94
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 95
},
{
"value": " },",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 96
},
{
"value": " {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 97
},
{
"value": " \"label\": \"Push release to GitHub\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 98
},
{
"value": " \"type\": \"shell\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 99
},
{
"value": " \"command\": \"c:\\\\scripts\\\\GitReleasePush.ps1\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 100
},
{
"value": " \"options\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 101
},
{
"value": " \"shell\": {",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 102
},
{
"value": " \"executable\": \"powershell.exe\",",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 103
},
{
"value": " \"args\": [",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 104
},
{
"value": " \"-noprofile\"",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 105
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 106
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 107
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 108
},
{
"value": " }",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 109
},
{
"value": " ]",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 110
},
{
"value": "}",
"PSPath": "C:\\work\\sample\\.vscode\\tasks.json",
"PSParentPath": "C:\\work\\sample\\.vscode",
"PSChildName": "tasks.json",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 111
}
]
},
{
"ItemType": "file",
"Path": "formats\\readme.txt",
"Content": {
"value": "These are formatting files for the module. This file can be deleted.",
"PSPath": "C:\\work\\sample\\formats\\readme.txt",
"PSParentPath": "C:\\work\\sample\\formats",
"PSChildName": "readme.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "directory",
"Path": "functions\\private"
},
{
"ItemType": "directory",
"Path": "functions\\public"
},
{
"ItemType": "file",
"Path": "functions\\private\\readme.txt",
"Content": {
"value": "This folder contains private module functions. This file can be deleted.",
"PSPath": "C:\\work\\sample\\functions\\private\\readme.txt",
"PSParentPath": "C:\\work\\sample\\functions\\private",
"PSChildName": "readme.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": "functions\\public\\readme.txt",
"Content": {
"value": "This folder contains public module functions. This file can be deleted.",
"PSPath": "C:\\work\\sample\\functions\\public\\readme.txt",
"PSParentPath": "C:\\work\\sample\\functions\\public",
"PSChildName": "readme.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": "tests\\readme.txt",
"Content": {
"value": "Module Pester tests for the module. This file can be deleted.",
"PSPath": "C:\\work\\sample\\tests\\readme.txt",
"PSParentPath": "C:\\work\\sample\\tests",
"PSChildName": "readme.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
},
{
"ItemType": "file",
"Path": "types\\readme.txt",
"Content": {
"value": "These are custom type extension files for the module. This file can be deleted.",
"PSPath": "C:\\work\\sample\\types\\readme.txt",
"PSParentPath": "C:\\work\\sample\\types",
"PSChildName": "readme.txt",
"PSDrive": "C",
"PSProvider": "Microsoft.PowerShell.Core\\FileSystem",
"ReadCount": 1
}
}
]
I should point out that the function creates some metadata that you can use to manage your layout.
$meta = [pscustomobject]@{
Created = (Get-Date -Format g)
CreatedBy = $env:USERNAME
Computername = $env:COMPUTERNAME
Source = (Convert-Path $SourcePath)
Version = $version
}
In Windows PowerShell, ConvertFrom-Json has an unexpected output format, so in a pipelined expression, piping to ForEach-Object works around it. I'll probably build a command to get information about the layout file to simplify this process.
Import a Module Layout
With this json file, I am ready to recreate it. All I need to do is specify the new location. This location will be a parent path that must already exist like C:\Scripts and the name of the new module. I can import the json file, convert it, and recreate the folders and files.
ForEach-Object {
#create all the directories first
if ($_.Itemtype -eq 'directory') {
if ($pscmdlet.ShouldProcess($_.path, "Create directory")) {
New-Item -Path $modpath -Name $_.path -ItemType Directory -Force
}
} #directory item
elseif ($_.itemtype -eq 'file') {
if ($pscmdlet.ShouldProcess($_.path, "Create file")) {
$newFile = (Join-Path -Path $modPath -ChildPath $_.path)
Set-Content -Path $newfile -Value $_.content
Get-Item -path $newFile
}
} #file item
} #foreach-object
Even though commands like New-Item support -WhatIf, which my import function also supports, I'm writing my own Whatif code. This is because the Set-Content commands will throw exceptions if the path doesn't exist.
If I'm happy with this, I can run it for real.
Within seconds I have a complete module structure created and ready for a new project.
The Functions
I will be including these functions in the new PSFunctionTools module I am writing. But you are welcome to try them out. Any feedback or suggestions would be welcome.
Function Export-ModuleLayout {
[cmdletbinding()]
[alias("eml")]
[OutputType("None","System.IO.FileInfo")]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "Specify the model module path.")]
[ValidateScript( { Test-Path $_ })]
[string]$SourcePath,
[Parameter(HelpMessage = "Define a version number for this layout.")]
[string]$Version = "1.0",
[Parameter(HelpMessage = "Specify the name of the Json file to store the result.")]
[ValidateNotNullOrEmpty()]
[ValidatePattern("\.json$")]
[string]$FilePath = ".\modulelayout.json",
[Parameter(HelpMessage = "Show the file result.")]
[switch]$Passthru
)
Write-Verbose "Starting $($MyInvocation.MyCommand)"
$out = [System.Collections.Generic.list[object]]::New()
$meta = [pscustomobject]@{
Created = (Get-Date -Format g)
CreatedBy = $env:USERNAME
Computername = $env:COMPUTERNAME
Source = (Convert-Path $SourcePath)
Version = $version
}
$out.Add($meta)
Push-Location
#change location to the folder so that the relative path structure can be used.
Set-Location -path $SourcePath
Write-Verbose "Exporting directory structure from $Sourcepath"
Get-ChildItem -Recurse |
ForEach-Object {
$relPath = (Resolve-Path -Path $_.fullname -Relative) -replace "\.\\", ""
Write-Verbose "Processing $relPath"
if ($_.Gettype().name -eq 'FileInfo') {
$f = [pscustomobject]@{
ItemType = "file"
Path = $relPath
Content = (Get-Content -Path $_.fullname)
}
$out.add($f)
}
else {
$d = [pscustomobject]@{
ItemType = "directory"
Path = $relPath
}
$out.Add($d)
}
} #foreach-object
Write-Verbose "Exporting module layout to $FilePath"
$out | ConvertTo-Json | Out-File -FilePath $FilePath
Pop-Location
if ($Passthru) {
Get-Item $Filepath
}
Write-Verbose "Ending $($myinvocation.MyCommand)"
}
function Import-ModuleLayout {
[CmdletBinding(SupportsShouldProcess)]
[alias("iml")]
[OutputType("none")]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "What is the name of your new module?")]
[ValidateNotNullOrEmpty()]
[ValidatePattern("^\w+$")]
[string]$Name,
[Parameter(HelpMessage = "What is the parent path? The default is the current location")]
[ValidateScript( { Test-Path $_ })]
[string]$ParentPath = ".",
[Parameter(Mandatory, HelpMessage = "Specify the path to the module layout json file.")]
[ValidateScript({Test-Path $_ })]
[ValidatePattern("\.json$")]
[string]$Layout
)
Write-Verbose "Starting $($MyInvocation.MyCommand)"
$ParentPath = Convert-Path $ParentPath
Write-Verbose "Creating module layout for $name under $parentpath using layout from $layout."
$modpath = New-Item -Path $ParentPath -Name $name -ItemType Directory -Force
<#
ConvertFrom-Json has a bug in Windows PowerShell so
piping the converted content to ForEach-Object and
passing each object back to the pipeline works around it
#>
Get-Content -path $Layout |
ConvertFrom-Json | ForEach-Object {$_} |
Sort-Object -Property ItemType |
ForEach-Object {
#create all the directories first
if ($_.Itemtype -eq 'directory') {
if ($pscmdlet.ShouldProcess($_.path, "Create directory")) {
New-Item -Path $modpath -Name $_.path -ItemType Directory -Force
}
} #directory item
elseif ($_.itemtype -eq 'file') {
if ($pscmdlet.ShouldProcess($_.path, "Create file")) {
$newFile = (Join-Path -Path $modPath -ChildPath $_.path)
Set-Content -Path $newfile -Value $_.content
Get-Item -path $newFile
}
} #file item
} #foreach-object
Write-Verbose "Ending $($MyInvocation.MyCommand)"
}
I already know of a few changes I want to make but this code is functional now and meets my requirements. Of course, I'm curious about what kind of requirements you might have.
Next time, I'll show you how I put all of recent posts together.
2 thoughts on “Fun with PowerShell Module Layout”
Comments are closed.