如何使用Invoke-Expression在模板内使用运行命令? [英] How to use run commands inside a template using Invoke-Expression?
问题描述
我正在为Arista开关配置创建一个文本文件模板,并且我刚刚弄清楚了如何使用Invoke-Expression替换模板中的变量.
I am creating a text file template for Arista switch configs, and I just worked out how to replace variables in my templates using Invoke-Expression.
现有的解决方案可以很好地用于奇异变量,但是我也想使用数组,稍后,我将有一些ForEach循环.
The existing solution works fine for singular variables, but I have arrays I'd like to use as well, and later on, I will have some ForEach loops.
我需要知道如何使用此方法在模板中实际执行操作,或者在将调用的表达式"转储到文件中之前对其进行编辑.
I need to know how to get this method to actually perform the operations inside my template, or alternatively, edit the 'invoked expression' before dumping it to a file.
当前脚本片段:
#Variables
$peerlink1int = "49"
$stamps = @("208","209","210","211")
$filename = ('SwitchConfig' + $(get-date -f 'MM-dd-yyyy HH-mm'))
$destination_file = ".\$filename.txt"
$Base = Get-Content '.\Arista\01AristaBase.txt' | out-string
$revisedBase = Invoke-Expression "`"$Base`""
$revisedBase | Out-File -append $destination_file
源文件片段:
interface Ethernet $peerlink1int
switchport trunk allowed vlan $Stamps[0]-$Stamps[-1],1111,1234
输出结果:
interface Ethernet 49
switchport trunk allowed vlan 208 209 210 212[0]-208 209 210 211[-1],1111,1234
我所期望的:
interface Ethernet 49
switchport trunk allowed vlan 208-211,1111,1234
顺便说一句,还有一种向我提出的不使用Invoke-Expression的方法.(无论我走到哪里,都会有人说使用它是不安全的.)但是,另一种方法只是替换文本.我需要一种编辑文本模板的方法,该方法允许我对生成的文本执行一些命令.
EDIT : As an aside, there was another method proposed to me that did not use Invoke-Expression. (Everywhere I go someone says it's unsafe to use.) However, this other method merely replaces text. I need a method of editing a text template that allows me to perform some commands on the resulting text.
例如,我需要一个ForEach循环,该循环采用的模板文本为:
For example, I need a ForEach loop that takes a template text of :
interface Vlan$stamps
description V$stamps
ip address 192.168.$stamps.2/25
vrrp $stampnum ip 192.168.$stamps.1
vrrp $stampnum description Stamp$stamps
并为$ stamps数组中的每个项目循环一次,这样您将获得:
And loops one time for every item in the array $stamps so you would get :
interface Vlan208
description V208
ip address 192.168.208.2/25
vrrp $stampnum ip 192.168.208.1
vrrp $stampnum description Stamp208
interface Vlan209
description V209
ip address 192.168.209.2/25
vrrp $stampnum ip 192.168.209.1
vrrp $stampnum description Stamp209
interface Vlan210
description V210
ip address 192.168.210.2/25
vrrp $stampnum ip 192.168.210.1
vrrp $stampnum description Stamp210
interface Vlan211
description V211
ip address 192.168.211.2/25
vrrp $stampnum ip 192.168.211.1
vrrp $stampnum description Stamp211
推荐答案
-
在可扩展字符串(
"..."
)内,只能简单变量引用直接嵌入 (例如,$ stamps
),以便嵌入 expressions (包括属性访问和索引编制),您需要将整个表达式包含在$(...)
(例如$($ Stamps [0])
)-请参见此答案.Inside expandable strings (
"..."
), only simple variable references can be embedded directly (e.g.,$stamps
), in order to embed expressions - which includes property access and indexing - you need to enclose the expression as a whole in$(...)
(e.g.,$($Stamps[0])
) - see this answer.您最终要寻找的是 字符串模板 ,PowerShell通过
$ ExecutionContext.InvokeCommand.ExpandString()逐字扩展(逐字)扩展为可扩展字符串,从而在某种程度上晦涩难懂.代码>
.What you're ultimately looking for is string templating, which PowerShell provides - somewhat obscurely - via on-demand expansion of verbatim (literal) strings as expandable strings via
$ExecutionContext.InvokeCommand.ExpandString()
.# Define the string template - note the $(...) around # $Stamps[0] and $Stamps[1] $template = @' interface Ethernet $peerlink1int switchport trunk allowed vlan $($Stamps[0])-$($Stamps[-1]),1111,1234 '@ # Define the variable referenced in the template $stamps = '208', '209', '210', '211' # better than: @("208","209","210","211") # Expand the template. $revisedBase = $ExecutionContext.InvokeCommand.ExpandString($template)
$ revisedBase
现在包含以下内容,这是您期望的:$revisedBase
now contains the following, which is what you expected:interface Ethernet switchport trunk allowed vlan 208-211,1111,1234
一个简单的演示,表明您也可以在循环中使用技术 ,并且按需扩展中使用了当时最新的变量值:
A simple demonstration that you can use the technique in a loop as well, with then-current variable values used in the on-demand expansion:
$template = '`$foo is now: $foo' foreach ($foo in 1..3) { $ExecutionContext.InvokeCommand.ExpandString($template) }
上面的照片:
$foo is now: 1 $foo is now: 2 $foo is now: 3
这篇关于如何使用Invoke-Expression在模板内使用运行命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!