Powershell中的数据类型转换问题

时间:2010-11-11 20:20:09

标签: sql-server-2008 powershell types

我正在编写一个Powershell脚本,它将从ZIP文件中提取一组数据文件,然后将它们附加到服务器上。我编写了一个处理解压缩的函数,因为我需要抓取所有文件以便我知道我正在附加的内容我从函数中返回:

function Unzip-Files
{
    param([string]$zip_path, [string]$zip_filename, [string]$target_path, [string]$filename_pattern)

    # Append a \ if the path doesn't already end with one
    if (!$zip_path.EndsWith("\")) {$zip_path = $zip_path + "\"}
    if (!$target_path.EndsWith("\")) {$target_path = $target_path + "\"}

    # We'll need a string collection to return the files that were extracted
    $extracted_file_names = New-Object System.Collections.Specialized.StringCollection

    # We'll need a Shell Application for some file movement
    $shell_application = New-Object -com shell.Application

    # Get a handle for the target folder
    $target_folder = $shell_application.NameSpace($target_path)

    $zip_full_path = $zip_path + $zip_filename

    if (Test-Path($zip_full_path))
    {
        $target_folder = $shell_application.NameSpace($target_path)
        $zip_folder = $shell_application.NameSpace($zip_full_path)

        foreach ($zipped_file in $zip_folder.Items() | Where {$_.Name -like $filename_pattern})
        {
            $extracted_file_names.Add($zipped_file.Name) | Out-Null
            $target_folder.CopyHere($zipped_file, 16)
        }
    }

    $extracted_file_names
}

然后我调用另一个函数来实际附加数据库(我删除了一些检查数据库是否存在的代码,但这不会影响这里的事情):

function Attach-Database
{
    param([object]$server, [string]$database_name, [object]$datafile_names)

    $database = $server.Databases[$database_name]

    $server.AttachDatabase($database_name, $datafile_names)

    $database = $server.Databases[$database_name]

    Return $database
}

我不断收到错误,“无法转换参数”1“,值为:”System.Object []“,”AttachDatabase“键入”System.Collections.Specialized.StringCollection“”。

我尝试在各个点明确声明数据类型,但这只是改变了我得到错误的位置(或类似的错误)。我还改变了参数声明,使用字符串集合而不是对象而没有运气。

我开始使用字符串集合,最终想要使用字符串集合。我似乎无法让Powerershell在某些时候停止尝试将其转换为通用对象。

有什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

看起来您应该使用逗号运算符返回名称:

  ...
  , $extracted_file_names
}

避免将集合“展开”到其项目并保留原始集合对象。

有几个这样的问题,这里只是一对:

Strange behavior in PowerShell function returning DataSet/DataTable

Loading a serialized DataTable in PowerShell - Gives back array of DataRows not a DataTable

更新:

这个类似的代码有效:

Add-Type @'
using System;
using System.Collections.Specialized;

public static class TestClass
{
    public static string TestMethod(StringCollection data)
    {
        string result = "";
        foreach (string s in data)
        result += s;
        return result;
    }
}
'@

function Unzip-Files
{
    $extracted_file_names = New-Object System.Collections.Specialized.StringCollection

    foreach ($zipped_file in 'xxx', 'yyy', 'zzz')
    {
        $extracted_file_names.Add($zipped_file) | Out-Null
    }

    , $extracted_file_names
}

function Attach-Database
{
    param([object]$datafile_names)

    # write the result
    Write-Host ([TestClass]::TestMethod($datafile_names))
}

# get the collection
$names = Unzip-Files

# write its type
Write-Host $names.GetType()

# pass it in the function
Attach-Database $names

正如预期的那样,它的输出是:

System.Collections.Specialized.StringCollection
xxxyyyzzz

如果我删除了建议的逗号,那么我们得到:

System.Object[]
Cannot convert argument "0", with value: "System.Object[]",
for "TestMethod" to type "System.Collections.Specialized.StringCollection"...

症状看起来相同,因此如果在Unzip-FilesAttach-Database来电之间的省略代码中没有其他不需要的转换/展开,则解决方案也应该可行。