Недокументированные изменения в обработке Powershell Scope v2/v3?

Предыстория: я писал сценарий powershell для переноса файлов из экземпляра Sharpoint 2010 в Windows Server '08 (с Powershell 2.x) в экземпляр Sharepoint 2013 в Windows Server '12 (с Powershell 3.х). У меня это работает, но я заметил изменение в том, как обрабатывается область.

Проблема: у меня есть следующий код, который запускается на обеих сеансах PSSessions ($param – это хэш-таблица значений параметров)

Invoke-Command -session $Session -argumentlist $params -scriptblock `
{
    Param ($in)
    $params = $in # store parameters in remote session

    # need to run with elevated privileges to access sharepoint farm
    # drops cli stdout support (no echo to screen...)
    [Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
    {
        # start getting the site and web objects
        $site = get-spsite($params["SiteURL"])
    })
}

Я заметил, что в удаленном сеансе PS 2.x назначение $site также назначается той же переменной в области Invoke-Command, то есть либо область передается, либо они имеют одну и ту же область. НО в удаленном сеансе PS 3.x назначение $site не меняет значение в Invoke-Command (настоящая дочерняя область).

Мое решение. Я написал функцию для вычисления правильной области видимости на каждом сервере, который он вызывает, а затем использовал возвращаемое значение в качестве входных данных для параметра Get-Variable и Set-Variable -Scope. Это решило мою проблему и позволяет назначать и получать доступ к переменным.

Function GetCorrectScope
{
    # scoping changed between version 2 and 3 of powershell
    # in version 3 we need to transfer variables between the
    # parent and local scope.
    if ($psversiontable.psversion.major -gt 2)
    {
        $ParentScope = 1 # up one level, powershell version >= 3
    }else
    {
        $ParentScope = 0 # current level, powershell version < 3
    }

    $ParentScope
}

Вопрос: где это задокументировано корпорацией Майкрософт? (Я не смог найти его в разделе about_scope на TechNet, где говорится, что относится как к 2.x, так и к 3.x и является стандартной ссылкой, которую я видел в других вопросах).

Кроме того, есть ли лучший/правильный способ сделать это?


person CodePartizan    schedule 29.08.2013    source источник


Ответы (1)


Это задокументировано в примечаниях к выпуску WMF 3 в разделе «ИЗМЕНЕНИЯ ЯЗЫКА WINDOWS POWERSHELL».

Блоки сценария, выполняемые как делегаты, выполняются в своей области

Add-Type @"
public class Invoker
{
    public static void Invoke(System.Action<int> func)
    {
        func(1);
    }
}
"@
$a = 0
[Invoker]::Invoke({$a = 1})
$a

Returns 1 in Windows PowerShell 2.0 
Returns 0 in Windows PowerShell 3.0
person Keith Hill    schedule 29.08.2013
comment
Спасибо. Мне даже потребовалось около 5 минут, чтобы найти нужный документ с примечаниями к выпуску (это изменение не было указано в примечаниях к бета-версии). Для тех, кто заинтересован, они доступны по адресу сайт загрузки Microsoft здесь - person CodePartizan; 29.08.2013