tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShell の Moduleインストール用スクリプトを作ってみた (続き)

以前、PowerShell Module を GitHub などから Clone した後に、 User Moduleパスにインストール (要はコピー) するスクリプトを公開しました。
PowerShell の Moduleインストール用スクリプトを作ってみた
前回のスクリプトは MS TechNetのやり方に沿ってちょろちょろいじったやつだったのですが、 フォルダ構造のコピーができない欠陥がありました。 今回、見直しを行い、フォルダ構造ごとコピーするようにしています。

GitHub

最新版はこちらから。
PowerShellUtil / Install-PowershellModule

利用方法

install.bat を実行すると、 $env:userProfile\documents\WindowsPowerShell\Modules にコピーされます。 詳しくは、ReadMe を参照してください。
ReadMe

そもそも Copy-Item Cmdlet ができないのは

Copy-Item Cmdlet単独 で フォルダ構造毎コピーできないのはどうにかしてほしいと感じています。 -Recurse は用途が違うからいいのですが、別のオプションを設けるなりは必要でしょう。 今回の Copy-Module で、フォルダ構造毎コピーする動作は実現しており、 普通の用途に利用してもいいのですがもやもやしたものがあります。 Stack Over Flow や、他の方も自作を試みているようですが...... どうなんでしょう。 このページを検索で見つけた人が必要としているであろう Copy-Module 部分を載せておきます。
Function Copy-Module{
    
    [CmdletBinding()]
    param(
        [parameter(
            mandatory,
            position = 0,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName)]
        [validateScript({Test-Path $_})]
        [string]
        $path,

        [parameter(
            mandatory,
            position = 1,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName)]
        [validateScript({(Get-Item $_).PSIsContainer -eq $true})]
        [string]
        $destination
    )

    if(Test-Path $path)
    {
        $rootpath = Get-Item $path
        
        Get-ChildItem -Path $path -File -Recurse | %{

            # Define target directory path for each directory
            if ($_.Directory.Name -ne $rootpath.Name)
            {
                $script:droot = Join-Path $destination $rootpath.Name
                $script:ddirectory = Join-Path $droot $_.Directory.Name
            }
            else
            {
                $script:ddirectory = Join-Path $destination $_.Directory.Name
            }

            # Check target directory path is already exist or not
            if(-not(Test-Path $ddirectory))
            {
                Write-Verbose "Creating $ddirectory"
                $script:ddirectorypath = New-Item -Path $ddirectory -ItemType Directory -Force
            }
            else
            {
                $script:ddirectorypath = Get-Item -Path $ddirectory
            }

            # Copy Items to target directory
            try
            {
                if (-not($_.PSIsContainer))
                {
                    $script:dpath = Join-Path $ddirectorypath $_.Name

                    Write-Verbose "Copying $($_.name) to $dpath"
                    Copy-Item -Path $_.FullName -Destination $ddirectorypath -Force -Recurse -ErrorAction Stop
                }
            }
            catch
            {
                Write-Error $_
            }
        }

        # return copied destination path
        return $droot
    }
    else
    {
        throw "{0} not found exception!" -f $path
    }
}
利用する際は、このようにします。
Copy-Module -path $path -destination $destination
たとえば、 c:\hoge を d:\hoge にコピーする場合はこうです。
Copy-Module -path c:\hoge -destination d:\hoge
ご参考となれば幸いです。