Powershell and XMLRPC - web-services

We are a Windows shop using Powershell extensively.We also have a Spacewalk that I would like to poll some data from as part of the existing Powershell script. Spacewalk API is exposed via XMLRPC.
I have spent some time searching for examples on how this can be done but the information is really scarce. The closest I could get was this link ( no longer available)
https://web.archive.org/web/20080202045713/http://thepowershellguy.com/blogs/posh/archive/2008/01/31/powershell-and-xmlrpc-posh-challenge-part-12.aspx
Lack of examples makes me think that I am looking in the wrong direction. I know about new-webserviceproxy and I used it for quering Sharepoint but I don't see anyone using it for XMLRPC calls.
It is trivial to write the call in Perl or Python but this is not what I need in this specific case...
Am I going the wrong way here?

Just implemented this myself, so I thought I'd pass it along.
You can actually download the DLL instead of compiling the source yourself - I found the DLL by using NuGet, but some say you can get it from the zip.
I decided to implement the interfaces in C# code within powershell to maximize portability / ease of development. If you want, you can compile the C# code as a DLL and load that using powershell, but you'll have to go back and recompile every time you want to make a change to the C# code. Here, powershell recompiles for you on the fly. (The only downside is that if you use the native windows powershell IDE, you have to close and reopen to clear your session every time you make a change to the C# code)
Here's an example of the OpenSubtitles API using XML-RPC.NET and powershell (not the cleanest code, but hopefully illustrates the XML-RPC.net usage):
$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)
My response is a bit delayed to the initial question, but hopefully this helps someone out there.

Have you looked at XML-RPC.NET? You would have to create a XmlRpcProxyGen class in C# that implements IXmlRpcProxy but once you've done that, you should be able to load that .NET assembly and use the proxy class from PowerShell.

Related

Convert Office 2007-2012 docs to pdf and image in Qt

We have developed an app that can import DOC/XLS files as images using LibreOffice. However, for PCs where Office is already installed, we would like to be able to use the installed MS Office. Most people are on MS Office version 2007-2010. I know that MS provide some sort of interoperability DLLs for this purpose but I haven;t seen any example of this being used with Qt.
Update - this answer looks interesting, can the same be done in Qt?
Convert Word file pages to jpg images using C#
PowerShell
It looks like you can do it with Powershell on the commandline pretty easily.
Open a QProcess, and run:
http://technet.microsoft.com/en-us/library/hh847736.aspx
powershell -Command "Import-Module MSOnline";"C:\Myscript.ps1"
(Download this script or convert it to C++ com calls.)
https://gallery.technet.microsoft.com/office/Script-to-convert-Word-f702844d
powershell -Command "Import-Module ConvertWordPocumentToPDF.psm1";"ConvertTo-OSCPDF -Path C:\path\to\document.docx"
So the end code for Qt probably could be something like:
QProcess * process = new QProcess();
// put code to pipe stdout and stderr from the QProcess to this exe's stdout, or to a TextEdit.
process->start("powershell.exe -Command \"Import-Module ConvertWordPocumentToPDF.psm1\";\"ConvertTo-OSCPDF -Path C:\\path\\to\\document.docx\"");
Com Object Access
DocumentBase.ExportAsFixedFormat Method
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.word.documentbase.exportasfixedformat.aspx
public void ExportAsFixedFormat(
string outputFileName,
WdExportFormat exportFormat,
bool openAfterExport,
WdExportOptimizeFor optimizeFor,
WdExportRange range,
int from,
int to,
WdExportItem item,
bool includeDocProps,
bool keepIRM,
WdExportCreateBookmarks createBookmarks,
bool docStructureTags,
bool bitmapMissingFonts,
bool useISO19005_1,
ref Object fixedFormatExtClassPtr
)
First get an instance of a Word.Application
then get an instance of a document using wdApplication.Documents.Open
then call wdDocument.ExportAsFixedFormat, with the parameters of:
$wdExportFormat = [Microsoft.Office.Interop.Word.WdExportFormat]::wdExportFormatPDF
$OpenAfterExport = $false
$wdExportOptimizeFor = [Microsoft.Office.Interop.Word.WdExportOptimizeFor]::wdExportOptimizeForOnScreen
$wdExportItem = [Microsoft.Office.Interop.Word.WdExportItem]::wdExportDocumentContent
$IncludeDocProps = $true
$KeepIRM = $true
$wdExportCreateBookmarks = [Microsoft.Office.Interop.Word.WdExportCreateBookmarks]::wdExportCreateWordBookmarks
$DocStructureTags = $true
$BitmapMissingFonts = $true
$UseISO19005_1 = $false
$wdStartPage = 0
$wdEndPage = 0
(but formatted for c++, not powershell)
then when it is completed, release the com objects.
http://msdn.microsoft.com/en-us/library/kw65a0we.aspx
I haven't tested either method, but I have ran Com objects from a Qt project before. Hope that helps.

How can I create a JSON webservice to store and retrieve data from a simple properties file?

How can I create a Java or Javascript JSON webservice to retrieve data from a simple properties file? My intention is to uses this as a global property storage for a Jenkins instance that runs many Unit tests. The master property file also needs to be capable of being manually edited and stored in source control.
I am just wondering what method people would recommend that would be the easiest for a junior level programmer like me. I need read capability at miniumum but, and if its not too hard, write capability also. Therefore, that means it is not required to be REST.
If something like this already exists in Java or Groovy, a link to that resource would be appreciated. I am a SoapUI expert but I am unsure if a mock service could do this sort of thing.
I found something like this in Ruby but I could not get it to work as I am not a Ruby programmer at all.
There are a multitude of Java REST frameworks, but I'm most familiar with Jersey so here's a Groovy script that gives a simple read capability to a properties file.
#Grapes([
#Grab(group='org.glassfish.jersey.containers', module='jersey-container-grizzly2-http', version='2.0'),
#Grab(group='org.glassfish.jersey.core', module='jersey-server', version='2.0'),
#Grab(group='org.glassfish.jersey.media', module='jersey-media-json-jackson', version='2.0')
])
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory
import org.glassfish.jersey.jackson.JacksonFeature
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
#Path("properties")
class PropertiesResource {
#GET
#Produces("application/json")
Properties get() {
new File("test.properties").withReader { Reader reader ->
Properties p = new Properties()
p.load(reader)
return p
}
}
}
def rc = new org.glassfish.jersey.server.ResourceConfig(PropertiesResource, JacksonFeature);
GrizzlyHttpServerFactory.createHttpServer('http://localhost:8080/'.toURI(), rc).start()
System.console().readLine("Press any key to exit...")
Unfortunately, since Jersey uses the 3.1 version of the asm library, there are conflicts with Groovy's 4.0 version of asm unless you run the script using the groovy-all embeddable jar (it won't work by just calling groovy on the command-line and passing the script). I also had to supply an Apache Ivy dependency. (Hopefully the Groovy team will resolve these in the next release--the asm one in particular has caused me grief in the past.) So you can call it like this (supply the full paths to the classpath jars):
java -cp ivy-2.2.0.jar:groovy-all-2.1.6.jar groovy.lang.GroovyShell restProperties.groovy
All you have to do is create a properties file named test.properties, then copy the above script into a file named restProperties.groovy, then run via the above command line. Then you can run the following in Unix to try it out.
curl http://localhost:8080/properties
And it will return a JSON map of your properties file.

TFS: Query for builds containing a specific changeset

I have a number of build definitions that get executed based upon a single branch in TFS (eg Main).
I'd like to (somehow) query TFS to find all builds containing a specific changeset number that I supply, and return a list of string of the names of the builds that TFS contains. Any kind of app (VS extension, CLI app, winforms, whatever) will do.
Note: this isn't a 'plz give me the code' request; I'm willing to hoof it and do serious work on this. Any pointers to documentation on how to query the database or SDK, or an example of how to query builds; just some place to start looking would be extremely helpful. Thanks.
The following snippet will crawl all Build Definitions of all Team Project of a Collection, and will check each and every build for an Association to the input changeset number:
using System;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace FindChangesetInBuild
{
class Program
{
static void Main(string[] args)
{
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfs:8080/tfs/collectionName"));
var versionControl = teamProjectCollection.GetService<VersionControlServer>();
var buildService = (IBuildServer)teamProjectCollection.GetService(typeof(IBuildServer));
var teamProjects = versionControl.GetAllTeamProjects(true);
foreach (var teamProject in teamProjects)
{
var buildDefinitions = buildService.QueryBuildDefinitions(teamProject.Name);
foreach (var buildDefinition in buildDefinitions)
{
var builds = buildService.QueryBuilds(buildDefinition);
foreach (var buildDetail in builds)
{
var changesets = InformationNodeConverters.GetAssociatedChangesets(buildDetail);
if (changesets.Any(changesetSummary => changesetSummary.ChangesetId == Convert.ToInt32(args[0])))
{
Console.WriteLine("Changeset was build in "+buildDetail.BuildNumber);
}
}
}
}
}
}
}
Needless to say, this is a brute force attack.You can further refine the code if you narrow down the list of buildDefinition, make focus on specific teamProjects etc. In any case I can hardly imagine the above to be useful as-is!Apart from (obviously) MSDN, a great resource for TFS-SDK is Shai Raiten's blog.For Build-Speficic examples, check also here & here for some possibly interesting SO posts.
You can use this little DB Query in TFS 2010 and just substitute 90264 with your changeset id.
USE Tfs_Warehouse
go
SELECT BuildName
FROM DimBuild
INNER JOIN FactBuildChangeset
ON DimBuild.BuildSK = FactBuildChangeset.BuildSK
WHERE FactBuildChangeset.ChangesetSK = 90264

Autogenerate Stub code in C++ to access a webservice?

I'm chancing my arm with this question.
I'm looking for a tool which will avoid doing a lot of coding by autogenerating much of the code to access a webservice.
I'm trying to help out someone who uses a 4GL system which doesn't support webservices. However they can access a win32 dll - which looks like being the easiest solution. All they need to do is occasionally call a function on a web service and get a result back.
Its been a loooong time since I wrote any C++ and my attempts at doing this have just exposed how rusty I am.
I've played around with the gsoap2 toolkit and MS's svcutil.exe tool for auto generating code.
They do what they are supposed to do but, unlike the add reference tool in visual studio with vb.net or c#.net, these toolkits don't generate a stub access class that I managed to find.
Instead they generate individual function calls for each method and you have to pass them httpcontexts and a whole load of other stuff - something I don't really want to have to learn how to do for a one off.
What I want to do is mechanical:
Take the wsdl definition
AutoGenerate the Webservice access code (done - gsoap2)
Write/generate a small stub to open the webservice and authenticate using basic authentication and to return an instance of the webservice instance class.
publish as a dll
The idea being to have a single dll with a single function like
getws(username, password, url)
which will return an object which exposes the methods of the webservices - a stub, nothing clever.
I know I'm clutching at straws here but does anyone know of a tool/way to avoid all the mechanical work and to end up with a simple class which I can modify to add authentication.
The webservice has around 30 methods - and I have to expose them all, each has a collection of parameters. Writing a stub class to call the functions generated by gsoap2 would be a lot of typing and a nightmare to get to work/debug. Theres got to be a better way.
What I want to do is the equivalent of the .net code below - VS autogenerates the WS code. All I have to do is expose it in my class.
Private Shared oWs As WS.publicws = Nothing
Public Shared Function GetWS(ByVal Username As String, ByVal password As String, ByVal URL As String) As WS.publicws
Dim oBinding As New ServiceModel.BasicHttpBinding
If Not oWs Is Nothing Then Return oWs
Dim oEndPoint As New ServiceModel.EndpointAddress(URL)
oBinding.Security.Mode = ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly
oBinding.Security.Transport.Realm = ServiceModel.HttpClientCredentialType.Basic
oWS = New WS.publicws (oBinding, oEndPoint)
oWS.ClientCredentials.UserName.UserName = username
oWS.ClientCredentials.UserName.Password = password
Using scope = New ServiceModel.OperationContextScope(oWs.InnerChannel)
ServiceModel.OperationContext.Current.OutgoingMessageProperties(System.ServiceModel.Channels.HttpRequestMessageProperty.Name) = httpRequestProperty
End Using
Return oWs
End Function

C++\IronPython integration example code?

I'm looking for a simple example code for C++\IronPython integration, i.e. embedding python code inside a C++, or better yet, Visual C++ program.
The example code should include: how to share objects between the languages, how to call functions\methods back and forth etc...
Also, an explicit setup procedure would help too. (How to include the Python runtime dll in Visual Studio etc...)
I've found a nice example for C#\IronPython here, but couldn't find C++\IronPython example code.
UPDATE - I've written a more generic example (plus a link to a zip file containing the entire VS2008 project) as entry on my blog here.
Sorry, I am so late to the game, but here is how I have integrated IronPython into a C++/cli app in Visual Studio 2008 - .net 3.5. (actually mixed mode app with C/C++)
I write add-ons for a map making applicaiton written in Assembly. The API is exposed so that C/C++ add-ons can be written. I mix C/C++ with C++/cli. Some of the elements from this example are from the API (such as XPCALL and CmdEnd() - please just ignore them)
///////////////////////////////////////////////////////////////////////
void XPCALL PythonCmd2(int Result, int Result1, int Result2)
{
if(Result==X_OK)
{
try
{
String^ filename = gcnew String(txtFileName);
String^ path = Assembly::GetExecutingAssembly()->Location;
ScriptEngine^ engine = Python::CreateEngine();
ScriptScope^ scope = engine->CreateScope();
ScriptSource^ source = engine->CreateScriptSourceFromFile(String::Concat(Path::GetDirectoryName(path), "\\scripts\\", filename + ".py"));
scope->SetVariable("DrawingList", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingList::typeid));
scope->SetVariable("DrawingElement", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingElement::typeid));
scope->SetVariable("DrawingPath", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingPath::typeid));
scope->SetVariable("Node", DynamicHelpers::GetPythonTypeFromType(AddIn::Node::typeid));
source->Execute(scope);
}
catch(Exception ^e)
{
Console::WriteLine(e->ToString());
CmdEnd();
}
}
else
{
CmdEnd();
}
}
///////////////////////////////////////////////////////////////////////////////
As you can see, I expose to IronPython some objects (DrawingList, DrawingElement, DrawingPath & Node). These objects are C++/cli objects that I created to expose "things" to IronPython.
When the C++/cli source->Execute(scope) line is called, the only python line
to run is the DrawingList.RequestData.
RequestData takes a delegate and a data type.
When the C++/cli code is done, it calls the delegate pointing to the
function "diamond"
In the function diamond it retrieves the requested data with the call to
DrawingList.RequestedValue() The call to DrawingList.AddElement(dp) adds the
new element to the Applications visual Database.
And lastly the call to DrawingList.EndCommand() tells the FastCAD engine to
clean up and end the running of the plugin.
import clr
def diamond(Result1, Result2, Result3):
if(Result1 == 0):
dp = DrawingPath()
dp.drawingStuff.EntityColor = 2
dp.drawingStuff.SecondEntityColor = 2
n = DrawingList.RequestedValue()
dp.Nodes.Add(Node(n.X-50,n.Y+25))
dp.Nodes.Add(Node(n.X-25,n.Y+50))
dp.Nodes.Add(Node(n.X+25,n.Y+50))
dp.Nodes.Add(Node(n.X+50,n.Y+25))
dp.Nodes.Add(Node(n.X,n.Y-40))
DrawingList.AddElement(dp)
DrawingList.EndCommand()
DrawingList.RequestData(diamond, DrawingList.RequestType.PointType)
I hope this is what you were looking for.
If you don't need .NET functionality, you could rely on embedding Python instead of IronPython. See Python's documentation on Embedding Python in Another Application for more info and an example. If you don't mind being dependent on BOOST, you could try out its Python integration library.