【问题标题】:Method invocation failed because [System.IO.FileInfo] does not contain a method named 'op_Addition'方法调用失败,因为 [System.IO.FileInfo] 不包含名为“op_Addition”的方法
【发布时间】:2016-12-20 18:40:47
【问题描述】:

我有以下 PowerShell 脚本,它将某些目录中的所有配置文件复制到我的本地系统。该脚本在我的许多服务器上都能正常运行,但在 4 台服务器上却失败了:

$source = @()
switch ([System.Net.Dns]::GetHostByName(($env:computerName)).HostName)
# populate an array with a list of paths that contain config files to be copied
{
    "SERVER1.DOMAIN"  {
        $source = @("C:\Program Files\MXC\", "C:\inetpub\wwwroot\")
        $target = "\\tsclient\C\Backups\Configs\SERVER1\"
    }
    "SERVER2.DOMAIN" {
        $source = @("C:\Program Files\MXC\")
        $target = "\\tsclient\C\Backups\Configs\SERVER2\"
    }
    "SERVER3.DOMAIN" {
        $source = @("C:\inetpub\wwwroot\ccb\001\", "C:\inetpub\wwwroot\eab\020\")
        $target = "\\tsclient\C\Backups\Configs\SERVER3\"
    }
    "SERVER4.DOMAIN" {
        $source = @("C:\inetpub\wwwroot\arv\drv\", "C:\inetpub\wwwroot\arv\imp\")
        $target = "\\tsclient\C\Backups\Configs\SERVER4\"
    }

function CopyConfigs ($configsList) {
    try {
        foreach ($file in $configsList) {
            # get the folder the config file lives in so it can be created in the target dir
            $folder = $file.DirectoryName | Split-Path -Leaf
            $dest = $target + $folder + "\"

            # if the $dest dir does not exist, create it.
            if (-not (Test-Path -Path $dest -PathType Container -ErrorAction SilentlyContinue)) {
                New-Item -ItemType Directory -Force -Path $dest
            }
            # copy the config file to the target directory
            Copy-Item $file -Destination  $dest -Force
        }
        Write-Host " End copying config files ====="
    } catch {
        Write-Host "** ERROR:  An error occurred while trying to copy the $file to $dest"
        return $Error[0].Exception
        exit 1
    }
}

try {
    # get the locations and names of the config files to copy
    foreach ($dir in $source) {
        $configsList += get-childitem -Recurse -Path $dir *.config -Exclude *.dll.config,*.vshost*,*app.config,*packages.config,*-*,*company.config*
    }
    CopyConfigs $configsList
} catch {
    Write-Host "** ERROR:  An error occurred while trying to get a list of config files to copy."
    Write-Host $Error[0].Exception 
    return 1
}

当它失败时,错误是:

方法调用失败,因为 [System.IO.FileInfo] 不包含名为“op_Addition”的方法。
   在 System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext,异常异常)
   在 System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame 框架)
   在 System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame 框架)
   在 System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame 框架)

我验证了 PowerShell 4.0 在所有系统上并且所有路径都有效。此脚本在 Windows Server 2008 R2 和 Wdows Server 2012 服务器上成功和失败。

我研究了“op_Addition”错误,但我没有看到它在某些时候有效,而在其他时候则无效。通常这个错误与试图操作不是数组的东西有关,但我相信我已经在我的脚本中解释了这一点。而且,它有时确实有效。

我真的不确定问题出在哪里。非常感谢您提供的任何帮助。

【问题讨论】:

  • $configsList 初始化为空数组 ($configsList = @()),否则您的第二次迭代将尝试追加到 FileInfo 对象而不是数组,这会失败,因为这些对象不会实现一个加法运算符。
  • 哦,伙计。我不敢相信我错过了。这正是脚本的问题所在。
  • 谢谢 Ansgar!

标签: powershell


【解决方案1】:

刚进入 Powershell,我遇到了同样的错误消息。我解决这个问题的方法是在我进行字符串连接的地方调用“.toString()”方法。我希望这对其他人有帮助

   foreach ($file in $configsList) {
        # get the folder the config file lives in so it can be created in the target dir
        $folder = $file.DirectoryName | Split-Path -Leaf

        # $dest = $target + $folder + "\" <-- these are objects, so make them strings as below:

        $dest = $target.ToString() + $folder.ToString() + "\"

        # if the $dest dir does not exist, create it.
        if (-not (Test-Path -Path $dest -PathType Container -ErrorAction SilentlyContinue)) {
            New-Item -ItemType Directory -Force -Path $dest
        }
        # copy the config file to the target directory
        Copy-Item $file -Destination  $dest -Force
    }
    Write-Host " End copying config files ====="

【讨论】:

    【解决方案2】:

    您需要先将变量初始化为数组。使用前添加:

    $configsList = @()
    

    【讨论】:

      【解决方案3】:

      另一种方法是在分配Get-ChildItem的结果时,将变量显式转换为文件对象数组:

      ...
          foreach ($dir in $source) {
              [System.IO.FileSystemInfo[]]$configsList += get-childitem -Recurse -Path $dir *.config -Exclude *.dll.config,*.vshost*,*app.config,*packages.config,*-*,*company.config*
          }
      ...
      

      【讨论】:

        猜你喜欢
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 2020-04-05
        • 1970-01-01
        相关资源
        最近更新 更多