2015-06-23 2 views
4

У меня есть сценарий, который прекрасно работает, но я хочу, чтобы улучшить свои знания Powershell и хотел бы знать, если есть более простой способ сделать это .....Функции и PowerShell Remoting

часть моего сценария соединяет к разъему и тянет bak список файлов и размеров на нем и экспортирует его в csv.

Я нашел функцию (Exportcsv), которая позволяет мне добавить к csv более ранние версии powershell.

В настоящее время я использую команду invoke для удаленного доступа к каждому серверу и запускаю скрипт в блоке сценария, но это означает добавление функции каждый раз. Таким образом, у меня есть функция в моем скрипте, но потом нужно повторить ее для каждого подключаемого сервера, чтобы он работал удаленно.

Есть ли способ передать локальную функцию удаленному серверу, поэтому мне не нужно добавлять для каждой команды вызова. не

Invoke-Command –ComputerName server –ScriptBlock { 
$wfile = "d:\folder\directorysize_H.csv" 
$xfile = "d:\folder\directorysize_F.csv" 

function ExportCSV { 
[CmdletBinding(DefaultParameterSetName='Delimiter', 
    SupportsShouldProcess=$true, ConfirmImpact='Medium')] 
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true, 
      ValueFromPipelineByPropertyName=$true)] 
[System.Management.Automation.PSObject] 
${InputObject}, 

[Parameter(Mandatory=$true, Position=0)] 
[Alias('PSPath')] 
[System.String] 
${Path}, 

#region -Append 
[Switch] 
${Append}, 
#endregion 

[Switch] 
${Force}, 

[Switch] 
${NoClobber}, 

[ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32', 
        'BigEndianUnicode','Default','OEM')] 
[System.String] 
${Encoding}, 

[Parameter(ParameterSetName='Delimiter', Position=1)] 
[ValidateNotNull()] 
[System.Char] 
${Delimiter}, 

[Parameter(ParameterSetName='UseCulture')] 
[Switch] 
${UseCulture}, 

[Alias('NTI')] 
[Switch] 
${NoTypeInformation}) 

begin 
{ 
# This variable will tell us whether we actually need to append 
# to existing file 
$AppendMode = $false 

try { 
    $outBuffer = $null 
    if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) 
    { 
     $PSBoundParameters['OutBuffer'] = 1 
    } 
    $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Csv', 
    [System.Management.Automation.CommandTypes]::Cmdlet) 


#String variable to become the target command line 
$scriptCmdPipeline = '' 

# Add new parameter handling 
#region Process and remove the Append parameter if it is present 
if ($Append) { 

    $PSBoundParameters.Remove('Append') | Out-Null 

    if ($Path) { 
    if (Test-Path $Path) {   
    # Need to construct new command line 
    $AppendMode = $true 

    if ($Encoding.Length -eq 0) { 
    # ASCII is default encoding for Export-CSV 
    $Encoding = 'ASCII' 
    } 

    # For Append we use ConvertTo-CSV instead of Export 
    $scriptCmdPipeline += 'ConvertTo-Csv -NoTypeInformation ' 

    # Inherit other CSV convertion parameters 
    if ($UseCulture) { 
    $scriptCmdPipeline += ' -UseCulture ' 
    } 
    if ($Delimiter) { 
    $scriptCmdPipeline += " -Delimiter '$Delimiter' " 
    } 

    # Skip the first line (the one with the property names) 
    $scriptCmdPipeline += ' | Foreach-Object {$start=$true}' 
    $scriptCmdPipeline += '{if ($start) {$start=$false} else {$_}} ' 

    # Add file output 
    $scriptCmdPipeline += " | Out-File -FilePath '$Path'" 
    $scriptCmdPipeline += " -Encoding '$Encoding' -Append " 

    if ($Force) { 
    $scriptCmdPipeline += ' -Force' 
    } 

    if ($NoClobber) { 
    $scriptCmdPipeline += ' -NoClobber' 
    } 
    } 
    } 
} 



$scriptCmd = {& $wrappedCmd @PSBoundParameters } 

if ($AppendMode) { 
    # redefine command line 
    $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
     $scriptCmdPipeline 
    ) 
} else { 
    # execute Export-CSV as we got it because 
    # either -Append is missing or file does not exist 
    $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
     [string]$scriptCmd 
    ) 
} 

# standard pipeline initialization 
$steppablePipeline = $scriptCmd.GetSteppablePipeline(
     $myInvocation.CommandOrigin) 
$steppablePipeline.Begin($PSCmdlet) 

} catch { 
    throw 
} 

} 

process 
{ 
    try { 
     $steppablePipeline.Process($_) 
    } catch { 
     throw 
    } 
} 

end 
{ 
    try { 
     $steppablePipeline.End() 
    } catch { 
     throw 
    } 
} 
} 

Write-Host "Removing old files from xxx" 

If (Test-Path $wfile){ 
      Remove-Item $wfile 
      } 

If (Test-Path $xfile){ 
      Remove-Item $xfile 
      } 

write-host "Getting _f details" 
get-childitem \\server\F$ -recurse |select directory, name, length|exportcsv $xfile -append -noclobber -notypeinformation 
write-host "Getting _H details" 
get-childitem \\server\H$ -recurse |select directory, name, length|exportcsv $wfile -append -noclobber -notypeinformation  
} 

ТИА

Энди

+0

@dugas Это означает, что нет никакого способа не включать тело функции? – Vesper

+0

@ Полагаю, что я не совсем понял вопрос и проголосовал неправильно, чтобы закрыть его - я отозвал этот голос. – dugas

ответ

4

Нет там не простой способ передать функцию на удаленных компьютерах, а кроме того, что вы уже делаете. :-) Однако вы можете положить все, что сценарий в файле (dirsize.ps1) и передать в Invoke-Command с помощью параметра FilePath:

Invoke-Command –ComputerName server –FilePath .\dirsize.ps1 

Файл будет скопирован на удаленные компьютеры и казнены.

0

попробовать это:

#Local Function 
function Get-Bits 
{ 
    Get-Service -Name BITS 
} 

Invoke-Command -ComputerName RemoteServer -ScriptBlock ${function:Get-Bits} 

лично я поставил все свои функции в файле psm1 другими словами, модуль на сетевом ресурсе и импортировать модуль в удаленном сеансе.

Смежные вопросы