我正在编写一个脚本来安装多个程序。
Install.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$here\includes\script1.ps1"
. "$here\includes\script2.ps1"
Write-Host "Installing program 1"
Install-ProgramOne
Write-Host "Installing program 2"
Install-ProgramTwo
script1.ps1
param (
[string] $getCommand = "msiexec /a program1.msi /q"
)
function Get-Command {
$getCommand
}
function Install-ProgramOne {
iex $(Get-Command)
}
script2.ps1
param (
[string] $getCommand = "msiexec /a program2.msi /q"
)
function Get-Command {
$getCommand
}
function Install-ProgramTwo {
iex $(Get-Command)
}
当包含两个文件时,$getCommand
变量将被覆盖。
C#中有名称空间,Ruby中有模块,但我无法弄清楚如何在Powershell中保持名称空间分开。
答案 0 :(得分:1)
$getCommand
变量不是变量本身,而是参数。指定了默认值的参数。也就是说,为点源脚本文件提供脚本参数并不是一个好主意。这些类型的文件通常只包含函数库和共享/全局变量。
V2和更高版本中更好的方法是使用模块。模块是变量和函数的容器,您可以在其中控制导出的内容和私有内容。这就是我对你的两个脚本所做的事情:
script1.psm1
# private to this module
$getCommand = "msiexec /a program1.msi /q"
function Get-Command {
$getCommand
}
function Install-ProgramOne {
iex $(Get-Command)
}
Export-ModuleMember -Function Install-ProgramOne
script2.psm1
# private to this module
$getCommand = "msiexec /a program2.msi /q"
function Get-Command {
$getCommand
}
function Install-ProgramTwo {
iex $(Get-Command)
}
Export-ModuleMember -Function Install-ProgramTwo
使用方式如下:
Import-Module $PSScriptRoot\script1.psm1
Import-Module $PSScriptRoot\script2.psm1
Install-ProgramOne
Install-ProgramTwo
答案 1 :(得分:0)
你是"点源"你的脚本而不是运行它们。这基本上意味着"将所有内容转储到GLOBAL名称空间"。如果你只是运行脚本而不是点源它们,那么它们每个都有自己的局部范围。一般来说,我认为应该运行带参数的脚本,而不是点源。
非点源的问题在于,默认情况下,您声明的功能将在脚本完成时超出范围。为避免这种情况,您可以改为定义您的函数:
function global:Install-ProgramOne
{
}
然后只运行脚本而不是dot-sourcing,$ getcommand将是您运行的每个脚本的本地脚本。