Powershell Импорт пользовательских C# CMDlets, нет доступных ExportedCommands

первый вопрос здесь :)

Поэтому мне нужно создать собственный CMDLet для Powershell 2.0, используя Visual Studio 2010 Express. Я следовал этому, казалось бы, простому руководству: http://blogs.msdn.com/b/saveenr/archive/2010/03/08/how-to-create-a-powershell-2-0-module-and-cmdlet-with-visual-studio-2010-screencast-included.aspx

Мой код почти такой же (даже пытался скопировать его код), но после вызова Import-Module "path_to_dll"

а затем вызовите Get-Module, я вижу свой импортированный модуль, но ExportedCommands недоступны.

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Binary     PowerShellCMDLetsLibrary  {}

Код С#:

namespace PowerShellCMDLetsLibrary
{
    [System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommon.Get,"RemedyXml")]
    public class Get_RemedyXml:System.Management.Automation.PSCmdlet
    {
    [System.Management.Automation.Parameter(Position = 0, Mandatory = true)]
    public string TicketID;

    protected override void ProcessRecord()
    {
    ...
    this.WriteObject(Result.InnerXml, true);
    }

Может быть ошибка, я просто не вижу


person Daniel    schedule 22.06.2011    source источник


Ответы (5)


Две вещи выскакивают из меня:

  1. TicketID — это поле, а не свойство.
  2. Атрибуция с увеличенным пространством имен затрудняет чтение кода.

Я подозреваю, что это № 1, но я не могу видеть дальше № 2, чтобы быть уверенным.

Надеюсь это поможет

person Start-Automating    schedule 22.06.2011
comment
Я нашел решение. Скопировал мою dll из сетевого пути UNC в локальный c:\ И теперь появляется команда. - person Daniel; 22.06.2011

Не знаю, репост ли, но:

Я нашел решение. Скопировал мою dll из сетевого пути UNC в локальный c:\ И теперь появляется команда.

person Daniel    schedule 22.06.2011

Если вы запускаете это вне сети или пути unc, вы должны добавить путь к своим .net довериям:

ie:

caspol -machine -addgroup 1. -url "file:\\\network\dir\\*" FullTrust  -n Uniquename

ХТХ,

Боб

person Bob Feller    schedule 29.08.2011
comment
Как отметил автор вопроса, Import-Module загружает командлеты, когда модуль хранится локально, но не при загрузке из сети. После предоставления полного доверия сетевому каталогу командлет Import-Module находит содержащиеся в нем командлеты. Большое спасибо! - person Lance U. Matthews; 02.12.2011
comment
Что ж, это сработало. Затем я попытался настроить свой модуль для работы с другого общего ресурса, и это не сработало, затем я вернулся к первому общему ресурсу и снова не смог заставить его работать. Я использовал CasPol.exe -ResolvePerm, чтобы убедиться, что моя сборка действительно получает полное доверие. Очень странно... - person Lance U. Matthews; 03.12.2011
comment
Догадаться. Я использовал 32-разрядную версию caspol.exe, но запускал 64-разрядные экземпляры PowerShell. Как только я внес изменения, используя 64-битную версию caspol.exe, все заработало. Не знаю, почему caspol.exe -resolveperm указал, что моя сборка не имеет ограничений, когда я предоставил FullTrust для ее сетевого пути, используя неправильную версию caspol.exe, ну да ладно. Смотрите мой ответ ниже. - person Lance U. Matthews; 03.12.2011

Это связано с безопасностью доступа для кода в .NET. По умолчанию сборка загруженный из сетевого ресурса, выполняется с ограниченными привилегиями, тогда как загруженный из локального хранилища вообще не имеет ограничений. К сожалению, командлет Import-Module не показывает, что ему не удалось импортировать командлеты в модуль, даже если он вызывается с параметром -Verbose.

Чтобы изменить набор разрешений, предоставленных определенному расположению в сети, используйте caspol.exe для создания новой группы кодов для этого местоположения:

caspol.exe -machine -addgroup 1.2 -url "file://server/share/directory/*" FullTrust

1.2 в приведенной выше команде относится к кодовой группе LocalIntranet, которая будет родителем новой кодовой группы. Следующая команда покажет, какие группы кодов определены, и может использоваться для отображения созданной вами группы:

caspol.exe -machine -listgroups

Обратите внимание, что в 32-разрядной версии Windows caspol.exe находится в папке %WinDir%\Microsoft.NET\Framework\CLR_VERSION\ (где для PowerShell 2.0 CLR_VERSION — это v2.0.50727), а в 64-разрядной версии Windows другая копия находится в папке %WinDir%\Microsoft.NET\Framework64\CLR_VERSION\. Каждая из 32- и 64-разрядных версий имеет собственный файл конфигурации безопасности (CONFIG\security.config), поэтому вам нужно убедиться, что вы применяете каждое изменение безопасности к обеим версиям, используя соответствующие caspol.exe.

Для отображения разрешений, которые будут предоставлены конкретной сборке, можно использовать следующую команду:

caspol.exe -resolveperm "//server/share/directory/assembly.dll"
person Lance U. Matthews    schedule 03.12.2011

Я в основном скопировал вставленный вами код. Я сделал Get-Module ClassLibrary2. Также TicketID работает.

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Binary     ClassLibrary2             Get-RemedyXml



using System.Management.Automation;

namespace ClassLibrary1
{
    [Cmdlet(VerbsCommon.Get, "RemedyXml")]
    public class Class1 : PSCmdlet
    {
        [Parameter(Position = 0, Mandatory = true)] 
        public string TicketID;

        protected override void ProcessRecord()
        {
            WriteObject(TicketID);
        }
    }
}
person Doug Finke    schedule 22.06.2011