如何使用Invoke-Expression在模板内使用运行命令? [英] How to use run commands inside a template using Invoke-Expression?

查看:44
本文介绍了如何使用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

推荐答案

  • 确实, Invoke-Expression 应该避免.

    在可扩展字符串("..." )内,只能简单变量引用直接嵌入 (例如, $ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆