Powershell函数返回值并进一步使用returnsnd变量

时间:2017-09-18 14:01:31

标签: function powershell csv

我不知道该功能在powershell中是如何工作的。我尝试过有点像c ++或c#,但这些语言我上次在7年前试过。

因此,当我尝试使用具有此功能的功能时

function whichcsv(){
    $location = New-Object System.Windows.Forms.OpenFileDialog
    $location.initialDirectory = $initialDirectory
    $location.filter = "CSV (*.csv)| *.csv"
    $location.ShowDialog()
    write-host $location.FileName "in Function"    
}

确定之后加载的csv的位置,但是一旦我尝试在函数外部加载变量$ location就使用NULL

使用write host语句,您可以看到它具有文件的完整路径。

一旦我尝试在代码之后将其加载到函数之后它就不会工作,因为它说它的NULL

...
    #Select which CSV
    whichcsv
...
    $CSV = Import-Csv -Path $location.FileName -UseCulture
    $y = $CSV | Select Inventarnummer
    $Filter = "Inventarnummer"

我试图将我的代码设置在int main(void)中,就像在c语言中一样,但我不知道如何处理它以及它本来应该在同一个scoope上所以它应该已经工作了但不知何故它不起作用,因为我只在控制台提示中得到所有,但什么都没发生

完整代码 for repro

#Importend:
#This is Work in Progress and not complited work.

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

#Function Assembling

Function SaveWorkingdestination ()
{
    $Saveworking = New-Object -Typename System.Windows.Forms.SaveFileDialog
    $Saveworking.filter = "CSV (*.csv)| *.csv"
    $Saveworking.ShowDialog()

    return $Saveworking
}

function Savefaileddestination ()
{
    $Savefailed = New-Object -Typename System.Windows.Forms.SaveFileDialog
    $Savefailed.filter = "CSV (*.csv)| *.csv"
    $Savefailed.ShowDialog()

    return $Savefailed
}


function Compare ($location)
{
    #work in progress   
    $CSV1 = Import-Csv -Path $location.FileName -UseCulture
    $CSV2 = Import-Csv -Path $location.FileName -UseCulture
    Compare-Object $CSV1 $CSV2 -property WhichColumn -IncludeEqual

    return comparedfilename

}


function whichcsv(){

    $location = New-Object System.Windows.Forms.OpenFileDialog
    $location.initialDirectory = $initialDirectory
    $location.filter = "CSV (*.csv)| *.csv"
    $location.ShowDialog()
    write-host $location.FileName "in Funktion"

}

function Checktrough ($y , $Filter,$Saveworking,$Savefailed)
{
    foreach($n in $y)
    {
        try {
            $Computer = [system.net.dns]::resolve($n.$Filter) | Select HostName,AddressList 
            $IP = ($Computer.AddressList).IPAddressToString
            Write-Host $n.$Filter $IP
            New-Object PSObject -Property @{IPAddress=$IP; Name=$n.$Filter} | Export-Csv $Saveworking.FileName -NoTypeInformation -Append
        } catch {
            Write-Host "$($n.$Filter) is unreachable."
            New-Object PSObject -Property @{Name=$n.$Filter} | Export-Csv $Savefailed.FileName -NoTypeInformation -Append
        }
    }
}

#int main (void)  #doesnt working so far
#{

    #Select which option Form

    $form = New-Object System.Windows.Forms.Form 
    $form.Text = "CSV Liste"
    $form.Size = New-Object System.Drawing.Size(300,300) 
    $form.StartPosition = "CenterScreen"

    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Point(75,195)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $OKButton
    $form.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Point(150,195)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $form.CancelButton = $CancelButton
    $form.Controls.Add($CancelButton)

    $label = New-Object System.Windows.Forms.Label
    $label.Location = New-Object System.Drawing.Point(10,20) 
    $label.Size = New-Object System.Drawing.Size(280,20) 
    $label.Text = "Welche CSV Liste soll geladen werden:"
    $form.Controls.Add($label) 

    $listBox = New-Object System.Windows.Forms.ListBox 
    $listBox.Location = New-Object System.Drawing.Point(10,40) 
    $listBox.Size = New-Object System.Drawing.Size(260,20) 
    $listBox.Height = 150

    [void] $listBox.Items.Add("AS400 Computer")
    [void] $listBox.Items.Add("AS400 Personalstamm")
    [void] $listBox.Items.Add("ADComputer")
    [void] $listBox.Items.Add("ADBenutzer")

    #Formclosed

    $form.Controls.Add($listBox) 

    $form.Topmost = $True

    $result = $form.ShowDialog()


    if ($result -eq [System.Windows.Forms.DialogResult]::OK)
    {

        #Select which CSV
        whichcsv

        $x = $listBox.SelectedItem

        switch ($x)
        {
            #Option 1 
            "AS400 Computer"
            {
                $CSV = Import-Csv -Path $location.FileName -UseCulture
                $y = $CSV | Select Inventarnummer
                $Filter = "Inventarnummer"
                #SaveWorkingdestination($Saveworking)
                #Export-Csv $Saveworking.FileName -NoTypeInformation -Append
            }

            #Option 2
            "AS400 Personalstamm" 
            {
                #not implemented yet
                $y = $CSV | Select SpaltennameBzwFilter
                $Filter = "Spaltennamme bzw Filter"
            }

            #Option 3
            "ADComputer" 
            {
                $CSV = Import-Csv -Path $location.FileName -Delimiter ',' 
                $y = $CSV | Select Name
                $Filter = "Name"
                SaveWorkingdestination
                Savefaileddestination
                Checktrough
            }

            #Option 4
            "ADBenutzer" 
            {
                #not implemented yet
                $y = $CSV | Select SpaltennameBzwFilter
                $Filter = "Spaltenname bzw Filter"
            }  
        }
    }
#}

也许有人知道如何帮助我从c语言中获取类似int main(void)之类的公共代码,或者如何从函数中获得正确的返回...如果仍然不清楚我会明确回答他们并编辑以使其工作

编辑:使用脚本部分它到目前为止工作得很好,但现在有一个格式问题,以获得更多的结构。或者在PowerShell脚本中没有包装,就像使用

的c语言一样
int main (void)
{
    ...
    code
    ...
}

3 个答案:

答案 0 :(得分:3)

在你的例子中:

function whichcsv(){
    $location = New-Object System.Windows.Forms.OpenFileDialog
    $location.initialDirectory = $initialDirectory
    $location.filter = "CSV (*.csv)| *.csv"
    $location.ShowDialog()
    write-host $location.FileName "in Function"    
}
在函数体中指定的

$location local 到函数的作用域。在PowerShell中,您可以从父作用域中读取变量,但写入变量默认情况下会创建本地副本,而不会保留在调用者的作用域中。

你想要做的是return它来自范围的价值,就像你在C语言中一样。

PowerShell中的警告是,函数体内的任何值表达式将输出任何东西,“冒泡”到调用者,而不仅仅是return的参数。因此,如果函数体内部的语句返回任何值,请确保捕获或抑制该输出:

function whichcsv(){
    $location = New-Object System.Windows.Forms.OpenFileDialog
    $location.initialDirectory = $initialDirectory
    $location.filter = "CSV (*.csv)| *.csv"
    [void]$location.ShowDialog() # <-- ShowDialog() returns a DialogResult, suppress it
    return $location.FileName # return the filename property value    
}

然后在调用范围内:

$CsvPath = whichcsv
函数返回后,

$CsvPath将包含$location.Filename的值

有关PowerShell中变量作用域的更多信息,请参阅about_Scopes help topic
有关return行为的详细信息,请参阅about_Return help topic
有关此行为的原因的详细信息,请查看pipelines

答案 1 :(得分:0)

您可能必须使用$script来更改可以使用变量的范围级别。要在函数外部使变量可用,请执行以下操作:

function whichcsv(){
    $location = New-Object System.Windows.Forms.OpenFileDialog
    $location.initialDirectory = $initialDirectory
    $location.filter = "CSV (*.csv)| *.csv"
    $location.ShowDialog()
    $script:locationfilename = $location.FileName
}

write-host "$($locationfilename) in Function"

答案 2 :(得分:0)

你必须将对象返回主程序。

function whichcsv(){

$location = New-Object System.Windows.Forms.OpenFileDialog
$location.initialDirectory = $initialDirectory
$location.filter = "CSV (*.csv)| *.csv"
$location.ShowDialog()
return $location.FileName  

}

$path= whichcsv
write-host $path