Powershell и XMLRPC

Мы - магазин Windows, широко использующий Powershell. У нас также есть Spacewalk, из которого я хотел бы опросить некоторые данные в рамках существующего скрипта Powershell. Spacewalk API предоставляется через XMLRPC.

Я потратил некоторое время на поиск примеров того, как это можно сделать, но информации действительно мало. Самая близкая, которую я мог получить, была эта ссылка (больше не доступен) https://web.archive.org/web/20080202045713/http://thepowershellguy.com/blogs/posh/archive/2008/01/31/powershell-and-xmlrpc-posh-challenge-part-12.aspx

Отсутствие примеров заставляет меня думать, что я смотрю не в ту сторону. Я знаю о new-webserviceproxy, и я использовал его для запроса Sharepoint, но я не вижу никого, кто бы использовал его для вызовов XMLRPC.

Писать вызов в Perl или Python тривиально, но это не то, что мне нужно в данном конкретном случае...

Я иду неправильным путем здесь?

2 ответа

Решение

Вы смотрели на XML-RPC.NET? Вам придется создать класс XmlRpcProxyGen в C#, который реализует IXmlRpcProxy, но как только вы это сделаете, вы сможете загрузить эту сборку.NET и использовать прокси-класс из PowerShell.

Просто реализовал это сам, так что я думал, что передам это.

На самом деле вы можете скачать DLL вместо компиляции исходного кода самостоятельно - я нашел DLL с помощью NuGet, но некоторые говорят, что вы можете получить ее из zip.

Я решил реализовать интерфейсы в коде C# в powershell, чтобы максимизировать переносимость / простоту разработки. Если вы хотите, вы можете скомпилировать код C# в виде DLL и загрузить его с помощью powershell, но вам придется возвращаться и перекомпилировать каждый раз, когда вы захотите внести изменения в код C#. Здесь PowerShell перекомпилирует для вас на лету. (Единственным недостатком является то, что если вы используете встроенную IDE PowerShell для Windows, вам придется закрывать и открывать заново, чтобы очистить сеанс каждый раз, когда вы вносите изменения в код C#)

Вот пример API OpenSubtitles, использующего XML-RPC.NET и powershell (не самый чистый код, но, надеюсь, иллюстрирующий использование XML-RPC.net):

$source = @'
namespace OpenSubtitlesAPI
{
    using CookComputing.XmlRpc;

    [XmlRpcUrl("http://api.opensubtitles.org/xml-rpc")]
    public interface IOpenSubtitles : IXmlRpcProxy
    {
        [XmlRpcMethod("LogIn")]
        XmlRpcStruct LogIn(string username, string password, string language, string useragent);

        [XmlRpcMethod("LogOut")]
        XmlRpcStruct LogOut(string token);

        [XmlRpcMethod("SearchSubtitles")]
        XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries);

        [XmlRpcMethod("SearchSubtitles")]
        XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries, int limit);
    }

    public class ProxyFactory
    {
        public static IOpenSubtitles CreateProxy()
        {
            return XmlRpcProxyGen.Create<IOpenSubtitles>();
        }
    }
}
'@

# Load XML-RPC.NET and custom interfaces
if ([Type]::GetType("OpenSubtitlesAPI.ProxyFactory") -eq $null)
{
    [Reflection.Assembly]::LoadFile("C:\path\to\CookComputing.XmlRpcV2.dll") | Out-Null
    $dynamicAssembly = Add-Type -TypeDefinition $source -ReferencedAssemblies ("C:\path\to\CookComputing.XmlRpcV2.dll")
}

# Set up proxy
$proxy = [OpenSubtitlesAPI.ProxyFactory]::CreateProxy()
$proxy.UserAgent = "user agent"
$proxy.EnableCompression = $true

# Log in
$LogInResponse = $proxy.LogIn("user name", "password", "language", "user agent")

# Build query
$query = New-Object CookComputing.XmlRpc.XmlRpcStruct
$query.Add("moviehash", "movie hash")
$query.Add("moviebytesize", "movie size")
$query.Add("sublanguageid", "language")
$queries = @($query)

# Search
$SearchResponse = $proxy.SearchSubtitles($LogInResponse.token, $queries)

# Log out
$LogOutResponse = $proxy.LogOut($LogInResponse.token)

Мой ответ немного задерживается на первоначальный вопрос, но, надеюсь, это поможет кому-то там.

Другие вопросы по тегам