pythonaro.com

Pythonaro blog

19 January 2010

Remote shutdown on Windows

This might sound useless or obvious to many, but i didn't know it and it made my life easier today...

If you ever need to shutdown a remote Windows machine, and you can't access it with Remote Desktop or similar tools, you can use Shutdown.exe from another Windows machine, like this: shutdown /m \\my-remote-host

Additional parameters can be seen with /? but the most useful ones are:

/r
reboot after shutdown
/f
force shutdown -- useful when the machine looks stuck, which is what happened to me today...
/d xx:yy
give a reason for reboot. See /? for the available codes.

I hope this means I can say goodbye to dangerous hard-reboots...

Labels: ,

posted by GiacomoL @ 10:54 AM   0 comments links to this post

05 July 2009

First impressions of OpenSolaris 2009.06, Windows Server 2008, and other various OSes

Having recently installed VMWare Server, I went on a "installfest of one": Windows Server 2008, Kubuntu 9.04, OpenBSD 4.5 and OpenSolaris 2009.06 are now happily chugging along on my server (which is apparently handling the situation without breaking a sweat -- impressive), with Arch Linux next on the list.

I have to say that I've been surprisingly impressed by the two "most commercial" offerings.

Windows 2008 feels really fast and lean. I don't like the new filemanager, but it looks like some of the infamous Windows bloat has been removed here and there. Getting asked for the Administrator password every 5 seconds is irritating, but at least the "Run as Administrator" menu item is more accessible than it used to be, so you can (mostly) preempt it. Also, it seems to work better with Samba, but this might be because Samba itself improved a lot (probably thanks to certain EU antitrust actions, but I digress).

I was even more impressed by OpenSolaris. Booting in a LiveCD before installation is always nice. The customized Gnome 2.24 (aka "Java Desktop System") is the most polished Gnome I've ever seen. The package manager makes it easy to get additional software (and to get rid of unwanted megabytes of localization files for all sorts of languages). It was a breeze to install NetBeans and its plugins (Python support!), I'll have to give it a spin. It's also curious to see in action Sun's typical "network philosophy": for example, /home folders are NFS mountpoints, which makes a lot of sense if you think about it. The drawbacks are that some things don't make sense: e.g. the Gnome utility to track free disk space goes bonkers (34 free gb when the disk is only 10...?). But these are details. I'd really like to spend some time learning permissions, ZFS, zones and all that; I hope I'll get some time at work.

In retrospect, configuring my first DNS server on OpenBSD 4.5 was almost uneventful. I'm not sure I even understand what I did, but it works :) I plan to expose this box to the Big Bad Internet at some point in the future, does anyone need a bit of space?

I guess the moral of the story is: VmWare server is very nice, when you have the right iron to run it on ;)

Labels: , , ,

posted by GiacomoL @ 7:37 PM   0 comments links to this post

04 March 2009

On The Burden Of Legacy

I recently thought it would be good to write a few utilities for one of the products I support. This product was built on DCOM (don't ask me why). Obviously, being a pythonaro, I just had to use Python. And so my tribulations began.

Python supports COM objects thanks to the lovely Win32 package by Mark Hammond. When you have a DLL that you want to use in python, run "makepy.py yourlib.dll" (or just makepy.py, and browse through the registered libraries to choose one) and lo, it's available as a first-class python module. So I do that, and start poking around with various stuff, and eventually I call a method that returns an object whose definition is in another DLL, so it only comes up as a PyIUnknown object. Ah well. I run makepy.py on the second DLL, to no avail.

After a bit of googling and fiddling, I finally stumbled on the right incantation.

myobj = win32com.client.Dispatch(myobj.QueryInterface(pythoncom.IID_IDispatch))
myobj = win32com.client.CastTo(myobj,'MyIClassName')
Basically, I have to find the right interface ID for the object, dispatch it, and then recast the object with a different type which is specified by a string. Man, isn't that ugly. Not because of having to recast (which I can understand) but because the recasting needs the class name as a string, you can't somehow derive it from the object. If you don't know the "secret" class name, you can't use its methods even if you know it's of the right type. From a modern OOP point of view, this is quite absurd... but there is an explanation.

COM was built when reflection was not yet mainstream, and types were static and immutable. Programmers were used to declare types for each variable, and if the type wasn't right, the compiler would cry. Polimorphism, reflection and dynamic interpreters were slowly reaching mainstream acceptance, but Microsoft had to retrofit them on top of existing frameworks, one feature at a time. The result was the incomplete hybrid I now have to deal with.

Well, I thought, this open-source CPython stuff in Redmond is considered akin to communism, no wonder it doesn't play well with old MS frameworks. Let's try to move further down "the Microsoft Way" and see if things improve: I shall use IronPython. After all, it's just a thin layer on top of the .Net CLR, right? Certainly it will be able to guess types a bit better...

So, a few installs later (you need at minimum the "Windows SDK 6.0" for good interop tools for .Net 2.0, plus the IronPython installer), there I was, trying to do the same thing.
The .Net version of makepy.py is called "tlbimp.exe", and it will basically build a new DLL to wrap the old one. You then import the new DLL in IronPython and lo, you can use the objects. But what happens when a function returns a reference to an object not defined in the DLL? Well, more or less the same thing as for win32com -- you get an unknown interface. So again,you have to wrap all the other DLLs, and explicitly instance these objects with the right type. Slightly better but not really that much different (so I'll stick to CPython, thank you).

As I said, this sort of explicit casting was perfectly acceptable 15 or even 10 years ago. But honestly, don't we live so much better without ? Why win32com and (more damning) IronPython cannot yet look up this sort of thing automatically? I understand that I'm working with legacy interop, but still... this sort of "programmer usability improvement" would help a lot in real-world situation where The Big Rewrite is simply not an option.

Labels: , , , , ,

posted by GiacomoL @ 4:10 PM   1 comments links to this post

07 January 2009

Adventures in Windows - Subinacl, Cscript and how I wasted an evening

My wife's desktop machine died a couple of days ago, and now Windows won't boot for some reason. After a few unsuccessful attempts at reviving it, I decided that it would be better to simply move her stuff to a spare machine we had laying around (which actually has better specs, but I digress).

So I duly connected the old disk to the new machine, and tried to copy across a few files. Windows said "Access is denied". Apparently, the account names between old and new machine where different, so Windows would show her files as belonging to an unknown account, and refusing access even to an Administrator.
I could have worked around this by booting a Knoppix livecd and taking over, but that would have been slow; I thought that surely there was a pure-Windows solution, some "admin command-line magic", that would fix things. And so the googling started...

There are basically two main elements in Windows file security: the Owner account, and the Access Control Lists (ACL) applied to the object (or inherited). So the first step was taking ownership of all the objects; I accomplished this with a simple script using WMI:

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colFolders = objWMIService.ExecQuery("Select * From Win32_Directory Where Name LIKE 'F:%'")
For Each objFolder in colFolders
    ' Add the input parameters.
    Set objInParam = objFolder.Methods_("TakeOwnerShipEx")._
        inParameters.SpawnInstance_()
    objInParam.Properties_.Item("Recursive") =  true
    objFolder.TakeOwnershipEx
    wscript.echo objFolder.Name
Next

The script uses a WQL query to retrieve all the directory objects, then takes ownership of them, using the Recursive option in order to take over all files included in the directory as well. I ran this from the command line with "cscript myfile.vbs" and it worked. (I have to say that for some reason this script failed on a few directories under "Program Files", but I simply ignored them.)

Now I could open any directory and set permissions on any object, but I still could not copy several files; this was because the ACL on these objects were set to refuse access to everyone but the old user. Unfortunately, I didn't know how to do that with WQL (I honestly don't know whether it's even possible); so I used SubInACL instead. This is a little tool you can download from Microsoft; it "enables administrators to obtain security information about files, registry keys, and services, and transfer this information from user to user, from local or global group to group, and from domain to domain." Exactly what I needed!

subinacl.exe /subdirectories "F:\*" /grant=Administrators=F

This one-liner simply grants Full (F) rights to any object under the F drive. A few minutes later, and I was finally able to copy the files.

And they say Unix is complicated? If this was an ext2 drive, I could simply have mounted the drive as root to do whatever I wanted. Windows administration is really a bitch.

Labels: , ,

posted by GiacomoL @ 11:24 PM   2 comments links to this post

27 August 2007

svn+ssh from Windows

Another one for Google, since currently the first hit is from a muppet advising to use a commercial product... If you want to connect to a Subversion repository using the standard SSH tunneling (svn+ssh), but you have a Windows workstation, you can use the Putty utilities. Here's what you need to do:
  1. Go to the Putty download page and download putty.exe, plink.exe, puttygen.exe and pageant.exe (since you are there, you might as well get the full installer, since stuff like pscp is also very useful). Put them in your Windows PATH (e.g. C:\Windows) -- you don't need this if you ran the installer).
  2. Start puttygen.exe and click Generate to generate a key. Enter the comment (usually your email) and a password. Then save the private key somewhere safe.
  3. Start Putty.exe and connect to your machine, with the user/pass you use when working in Subversion.
  4. go back to the puttygen window, and copy the generated key text
  5. in the open ssh session, type
    echo '

    then right-click and Paste then
    ' >> ~/.ssh/authorized_keys

    then Enter
  6. close Puttygen ad exit the ssh session, start Pageant. A small icon will appear in your taskbar.
  7. Right-click on the icon, "Add key". Select your private key and OK, enter the password.
  8. open a new command window, and try this:
    plink your-username@your.host.com

    You shouldn't be asked for a password, and be straight in. Perfect! One last thing...
  9. go to your %APPDATA% directory (C:\Documents & Settings\your-name\Application Data), and enter the Subversion folder. Open the "config" file, locate the [tunnel] section and add this line before saving & closing:
    ssh = plink
  10. Now you should be set! Try doing
    svn co svn+ssh://your-username@your.host.com/your/prj

I don't know if using TortoiseSVN or other UI this process can be easier or more complicated. This works, and it will give you the standard basic svn+ssh features.

Technorati Tags: , , ,

Labels: , , , ,

posted by GiacomoL @ 11:54 AM   0 comments links to this post