未加星标

PSDepend: PowerShell Dependencies

字体大小 | |
[系统(windows) 所属分类 系统(windows) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏
Rambling

The first weeks of August 2016 were great. I spent most of my time relaxing on the porch, with some sailing, swimming, and ice cream mixed in.


PSDepend: PowerShell Dependencies

Of course, I couldn’t help myself, and spent a little time on a fun side project: PSDepend

PSDepend

What is this PSDepend thing? Long story short, it’s a way for you to tell PowerShell that you need certain PowerShell modules, git repositories, and other dependencies, using a small requirements.psd1 file.

What’s a requirements.psd1?

Here’s a quick example to illustrate the basics of a requirements.psd1 :

@{ psake = 'latest' Pester = 'latest' BuildHelpers = '0.0.20' PSDeploy = '0.1.21' 'RamblingCookieMonster/PowerShell' = 'master' }

This is pretty straightforward: from the PowerShell Gallery, we want the latest Pester and psake, and specific versions of BuildHelpers and PSDeploy. We also want to download a GitHub repo’s master branch.

I can now run Invoke-PSDepend against this requirements file, and pull in my dependencies.

Before we dive in, why would we want something like this?

Why PSDepend?

You can probably come up with more creative scenarios, but here are a few use cases that came to mind:

Provide functional dependency documentation for a project Enable something like a module-focused virtual environment for PowerShell Simplify sharing code with non-PowerShell-savvy folks Help ensure a consistent runtime environment and improve portability for PowerShell solutions Quickly set up a fresh dev/test/etc. PowerShell environments

How many times have you had to describe the steps to resolve prerequisites for a function, module, script, or other PowerShell code? Did you have to start from ground zero and explain what a module is and how to install it?

It turns out, many other languages have solved this problem. In python, you might pip install -r requirements.txt . In Ruby, you might bundle install . In PowerShell? You hard code solution-specific logic into your code, abstract this out into configuration management, or just manually install the prerequisites and hope you don’t forget about them if you re-deploy your system.

Shouldn’t something like this already exist? Michael Willis has already started on the awesome looking PSRequire - unfortunately, I still need to support PowerShell pre-v5, so the class-based PSRequire wasn’t for me; time for a side project!

What dependencies does PSDepend support?

At the time of writing, we support a few dependency types:

PSGalleryModule : Modules from the PowerShell Gallery, via PowerShellGet Package : Install a package using the PackageManagement module PSGalleryNuget : Modules from the PowerShell Gallery, without the need of PowerShellGet Git : Clone a repo and checkout a branch/commit/tag GitHub : Download a specific branch or commit from a repo on GitHub, and extract a PowerShell module if we find it (Thanks to Doug Finke for some starter code !) FileDownload : Download a file FileSystem : Copy a file or folder Task : Run a pre-defined PowerShell script Command : Run a PowerShell command

More to come - Nuget for example - but we’d love ideas or pull requests! You can always run Get-PSDependType to view available dependency types.

That syntax seems too simplistic

It probably is! That being said, the simple syntax we showed with a ModuleName = 'Version' and ’Account/Repo’ = 'Version' is just a shortcut. We also support a more flexible syntax:

@{ PSDeploy_0_1_21 = @{ DependencyType = 'PSGalleryNuget' Name = 'PSDeploy' Version = '0.1.21' Target = "C:\ProjectX" Tags = 'prod' DependsOn = 'BuildHelpers' AddToPath = $True PostScripts = 'C:\SomeScripts.ps1' } # You can still mix in simple syntax BuildHelpers = '0.0.20' }

Whew! That was a bit convoluted. What does it actually do?

We make sure to install the BuildHelpers dependency first ( DependsOn ) We download PSDeploy, version 0.1.21, from the PowerShell Gallery ( Name , Version , DependencyType ) We use a nuget.exe (and grab it for you if you don’t have it), rather than depend on PowerShellGet (PSGalleryNuget DependencyType ) We install this to C:\ProjectX\PSDeploy ( Target ) We only run the PSDepend install if Invoke-PSDepend is called with -Tags prod ( Tags ) We add C:\ProjectX ( Target ) to $ENV:PSModulePath ( AddToPath ) We run C:\SomeScripts.ps1 after we’ve downloaded PSDeploy ( PostScripts )

You can run Get-Help Get-Dependency , or Get-Help about_PSDepend_Definitions for details on standard attributes, and Get-PSDependType SomeTypeName -ShowHelp to see the help for a specific dependency type.

Let’s dive in and start using PSDepend.

Getting Started with PSDepend

Getting up and running with PSDepend is simple!

# PowerShell 5 or PowerShellGet installed: Install-Module PSDepend # PowerShell 3 or 4, curl|bash bootstrap. Read before running something like this... Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://raw.github.com/ramblingcookiemonster/PSDepend/Examples/Install-PSDepend.ps1') # Git # Download the repository # Unblock the zip # Extract the PSDepend folder to a module path (e.g. $env:USERPROFILE\Documents\windowsPowerShell\Modules\) # Import and start exploring Import-Module PSDepend Get-Command -Module PSDepend Get-Help about_PSDepend

That’s it! Keep in mind we bootstrap nuget.exe when you import the module for the first time, unless you have it in your path or adjust the config file .

Now that you have PSDepend, we can start kicking the tires.

What commands can I run?

PSDepend includes commands to do things, and to help explore PSDepend:

Get-PSDependType

This is a quick way to see what dependency types are available:

Get-PSDependType DependencyType Description DependencyScript -------------- ----------- ---------------- FileDownload Download a file C:\...PSDependScripts\FileDownload.ps1 FileSystem Copy a file or folder C:\...PSDependScripts\FileSystem.ps1 Git Clone a git repository C:\...PSDependScripts\Git.ps1 PSGalleryModule Install a PowerShell m... C:\...PSDependScripts\PSGalleryModule.ps1 PSGalleryNuget Install a PowerShell m... C:\...PSDependScripts\PSGalleryNuget.ps1 Task Support dependencies b... C:\...PSDependScripts\Task.ps1 ...

You can also use it to get help information for one of these types:

Get-PSDependType PSGalleryModule -ShowHelp ... SYNOPSIS Installs a module from a PowerShell repository like the PowerShell Gallery. SYNTAX C:\Users\wframe\Documents\GitHub\PSDepend\PSDepend\PSDependScripts\PSGalleryModule.ps1 [[-Dependency] <PSObject[]>] [[-Repository] <String>] [-Force] [-Import] [<CommonParameters>] DESCRIPTION Installs a module from a PowerShell repository like the PowerShell Gallery. Relevant Dependency metadata: Name: The name for this module Version: Used to identify existing installs meeting this criteria, and as RequiredVersion for installation. Defaults to 'latest' Target: Used as 'Scope' for Install-Module. If this is a path, we use Save-Module with this path. Defaults to 'AllUsers' AddToPath: If target is used as a path, prepend that path to ENV:PSModulePath ...

What else can we do?

Get-Dependency

If you want to parse a requirements.psd1 file, you can run Get-Dependency .

By default this will look for a requirements.psd1 or a *.depend.psd1 file in the current path. You can also use -Recurse , or specify a -Path . Here’s the output from our flexible psd1 example above:

Get-Dependency | Select-Object -Property * DependencyFile : C:\temp\requirements.psd1 DependencyName : BuildHelpers DependencyType : PSGalleryModule Name : BuildHelpers Version : 0.0.20 Parameters : Source : Target : AddToPath : Tags : DependsOn : PreScripts : PostScripts : PSDependOptions : Raw : DependencyFile : C:\temp\requirements.psd1 DependencyName : PSDeploy_0_1_21 DependencyType : PSGalleryNuget Name : PSDeploy Version : 0.1.21 Parameters : Source : Target : C:\ProjectX AddToPath : True Tags : prod DependsOn : BuildHelpers PreScripts : PostScripts : C:\SomeScripts.ps1 PSDependOptions : Raw : {Tags, Version, AddToPath...}

Notice that BuildHelpers is listed first (PSDeploy_0_1_21 DependsOn it). You can use Get-Dependency to verify that PSDepend will read your requirements.psd1 file as expected.

So! We know how to read a requirements file, but how do we actually install these dependencies?

Invoke-PSDepend

Invoke-PSDepend can kick off a test, install, or import of a dependency. By default, it will search recursively for any requirements.psd1 file, or *.depend.psd1 file under the current path, similar to Invoke-Pester or Invoke-PSDeploy , and run the install action.

Using the same requirements.psd1, let’s verify that our dependencies aren’t already in place:

Invoke-PSDepend C:\temp\requirements.psd1 -Test | Select-Object -Property Dependency* DependencyFile DependencyName DependencyType DependencyExists -------------- -------------- -------------- ---------------- C:\temp\requirements.psd1 BuildHelpers PSGalleryModule False C:\temp\requirements.psd1 PSDeploy_0_1_21 PSGalleryNuget False Invoke-PSDepend C:\temp\requirements.psd1 -Test -Quiet False

Now, let’s kick off PSDepend:

Invoke-PSDepend -Path C:\temp

After a couple seconds, our dependencies are in place:

Invoke-PSDepend C:\temp\requirements.psd1 -Test Quiet True

We can verify that the Target for PSDeploy was added to the PSModulePath:

$ENV:PSModulePath C:\ProjectX;C:\Users\wframe...

Perhaps we want to import these dependencies, and validate that they imported:

Invoke-PSDepend C:\temp\requirements.psd1 -Import Get-Module -Name BuildHelpers, PSDeploy | Select-Object -Property Version, Path Version Path ------- ---- 0.0.20 C:\Program Files\WindowsPowerShell\Modules\BuildHelpers\0.0.20\BuildHelpers.psm1 0.1.21 C:\ProjectX\PSDeploy\PSDeploy.psm1

Enough blather, let’s cover a practical scenario where this might come in handy!

Example: Module Based Virtual Environments

PSDepend can help create minimalistic virtual environments in a few ways:

Prepending $ENV:Path with one or more paths Prepending $ENV:PSModulePath with one or more paths Importing modules Installing modules and files in deterministic locations

Let’s pretend we’re working on ProjectX. Our systems may have different versions of modules, perhaps due to conflicting requirements from other projects. This is a common theme with languages like Python and Ruby, and will likely become more of an issue in PowerShell.

Do we just replace those modules and break things? Do we need to include our own custom code for dependencies with each of our projects, perhaps using PowerShell 5’s side-by-side versioning? No thank you, I’ll try this with PSDepend!

Demo

Once we’ve identified our dependencies, we build a requirements.psd1 file:

@{ # Set some global, override-able defaults PSDependOptions = @{ Target = 'C:\ProjectX' } # Grab some modules PSSlack = '0.0.15' ImportExcel = '2.2.7' 'Posh-SSH' = 'latest' # Download a GitHub repo 'ramblingcookiemonster/PowerShell' = 'master' # Grab an internal module 'PSAMS' = @{ DependencyType = 'FileSystem' Source = '\\FileServer01\PowerShell\PSAMS' } # Download a file 'psrabbitmq.dll' = @{ DependencyType = 'FileDownload' Source = 'https://github.com/RamblingCookieMonster/PSRabbitMq/raw/master/PSRabbitMq/lib/RabbitMQ.Client.dll' } }

I’ll save this in C:\ProjectX\requirements.psd1, and invoke it:

Invoke-PSDepend C:\ProjectX -Force

We can verify that we have the resulting files:

Invoke-PSDepend C:\ProjectX -Test Quiet True Get-ChildItem C:\ProjectX | Select-Object -Property Name Name ---- ImportExcel Posh-SSH PowerShell psams PSSlack RabbitMQ.Client.dll requirements.psd1

Finally, if we need these modules in our project, we can import them with a one liner:

# Import dependencies! Invoke-PSDepend C:\ProjectX Import -Force # Trust, but verify Get-Module -Name PSSlack, ImportExcel, Posh-SSH, PSAMS ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Script 2.2.7 ImportExcel {Add-WorkSheet, BarChart, Col... Manifest 1.7.6 Posh-SSH {Get-SCPFile, Get-SCPFolder, ... Script 0.0.1 psams {Get-AmsLab, Get-AmsLabMember... Script 0.0.15 PSSlack {Find-SlackMessage, Get-PSSla...

That’s it! A small requirements.psd1 file, and we now have our modules loaded and available to re-use in C:\ProjectX , even if our $ENV:PSModulePath includes these modules at incompatible versions.

Next Steps

So! An early version of PSDepend is out there, you can find the raw code on GitHub .

If this is something you might use, kick the tires a bit! Feel free to submit an issue for an idea or bug, or a pull request to fix bugs, code smells, documentation, lack of tests, or anything else that you think might help.

Cheers!

Thumbnail credit

本文系统(windows)相关术语:三级网络技术 计算机三级网络技术 网络技术基础 计算机网络技术

主题: PowerShellGitGitHubSlackRubyRabbitMQWindowsSG.NetERP
分页:12
转载请注明
本文标题:PSDepend: PowerShell Dependencies
本站链接:http://www.codesec.net/view/520856.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(windows) | 评论(0) | 阅读(40)