【问题标题】:Execute PowerShell script from Perl script从 Perl 脚本执行 PowerShell 脚本
【发布时间】:2014-01-06 20:16:44
【问题描述】:

我正在尝试从 Perl 脚本执行 PowerShell 脚本并遇到一些错误。该脚本在 Windows Server 2012 机器上作为 Windows 服务运行。我要做的是确定用户是否存在 Exchange 邮箱。以前的 Perl 代码是为了连接到已经运行多年的 Exchange 2003 而编写的。我们现在正在升级到 Exchange 2013,需要更新代码,以便它调用 PowerShell 脚本来执行此任务。 PowerShell 脚本将检查用户是否有邮箱,如果有则返回一个字符串。

Perl 代码

sub mailboxExists
{
  my ($argstr) = @_;
  my ($username) = parseArgs($argstr);

  # Get the user's dn
  my $dn = userExists($username);
  if(!$dn)
  {
    print $CLIENT "ERR User does not exist, so mailbox can not\n";
    return undef;
  }

  # Search

  $result = 'C:\Windows\System32\PowerShell\v1.0\powershell.exe -command "C:\LDIAD\PS\mailboxExists.ps1 $username"';
}

PowerShell 脚本 - 目前正在使用 Exchange 2007 进行测试,因为我们尚未部署 2013,但代码将大部分相同。

#Add the Exchange 2007 snapins
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Support

#Start the script
$user = Get-User -Identity $username
If ($user.RecipientType -eq "UserMailbox")
{
"1"
}
Else
{
"0"
}

PowerShell 代码工作正常,我认为问题是我在 Perl 中调用 PS 脚本的命令?我的 Perl 知识非常有限。这是来自不再在这里的员工的代码。我只添加了应该执行 PowerShell 脚本的行。

【问题讨论】:

  • 简答:使用像$result = `command`; 这样的反引号来执行command——但还有比这更灵活、更安全的方法。
  • 可以分享更灵活更安全的方法吗?我非常愿意接受建议以使这变得更好。

标签: perl powershell


【解决方案1】:

单引号、双引号和反引号字符在 Perl 中都有不同且特定的含义,混淆它们会使您的程序以意想不到的方式运行。

对于"double quotes" 内的文本,Perl 会插入变量并重新解释前面有反斜杠的字符

$foo = "bar";
print "\t$foo\n";       # outputs:  <TAB> bar <NEWLINE>

'single quotes' 内部,Perl 不插入变量,并且将反斜杠视为文字反斜杠字符,除非它后跟另一个反斜杠或单引号字符。使用它们来告诉 Perl 按字面意思对待引号内的文本。

$foo = "bar";
print '\t$foo\n';       # outputs: <BACKSLASH> t <DOLLAR> foo <BACKSLASH> n

对于反引号内的文本(抱歉,标记不可用),Perl 做了两件事。 (1) 重新解释字符串,就好像它在双引号内(插入变量,替换转义字符序列),以及 (2) 将生成的字符串作为命令传递给操作系统以运行,返回命令的输出

$foo = "bar";
print `ls /tmp/$foo 2>&1`;
# possible output:    ls: cannot access /tmp/bar: No such file or directory


回到原来的问题:你想运行命令

C:\Windows\System32\PowerShell\v1.0\powershell.exe -command "C:\LDIAD\PS\mailboxExists.ps1 $username"

在您的操作系统上,“$username”被 Perl 变量 $username 的字符串值替换,并且您希望将该命令的输出分配给变量 $result。以下是一些实现这一目标的方法:

  1. 使用内插反引号,转义\

    $result = `C:\\Windows\\System32\\PowerShell\\v1.0\\powershell.exe -command "C:\\LDIAD\\PS\\mailboxExists.ps1 $username"`;
    
  2. 使用单引号将文字字符串分配给临时变量

    my $powershell = 'C:\Windows\System32\PowerShell\v1.0\powershell.exe';
    my $mboxScript = 'C:\LDIAD\PS\mailboxExists.ps1';
    $result = `$powershell -command "$mboxScript $username"`;
    

【讨论】:

    【解决方案2】:

    试着跑起来

    $scriptpath="C:\LDIAD\PS\mailboxExists.ps1 $username";
    $exepath = "C:\Windows\System32\PowerShell\v1.0\powershell.exe";
    

    然后使用任一

    $result = `$exepath -File $scriptpath`;
    

    system("$exepath -File $scriptpath");
    

    【讨论】:

      【解决方案3】:

      在 Windows 7 上,以下工作。 是的,需要进行大量清洁工作,但目前对我有用。

      $constant = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe";
      $param1 = " -psc ";
      $param2 = "\"C:\\Program\ Files\ (x86)\\VMware\\Infrastructure\\vSphere\ PowerCLI\\vim.psc1\" -noe -c";
      $param3 = " \". \\\"C:\\Program\ Files\ (x86)\\VMware\\Infrastructure\\vSphere\ PowerCLI\\Scripts\\Initialize-PowerCLIEnvironment.ps1\\\"\"";
      
      $test = $param1.$param2.$param3;
      open (IN, "| \"$constant\" $test") or die "$!";
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多