Instantly share code, notes, and snippets.
Created
April 4, 2011 17:18
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(1)
1
You must be signed in to fork a gist
-
Save jbarber/902008 to your computer and use it in GitHub Desktop.
Dumping sharepoint lists from perl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# Script to retrieve a list from sharepoint, which contains | |
# /etc/hosts type information and dump it in hosts format | |
# | |
# It's recomended to enter the username on the command line and let it prompt | |
# for the password | |
# | |
# The column names for the list items are hard coded. | |
# | |
# Much shamelessly taken from "james": | |
# http://www.squish.net/log/2008/10/11/perl-sharepoint/ | |
# | |
# As well as the use'd modules, this also requires Authen::NTLM | |
# | |
# MS documentation: | |
# http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems.aspx | |
use strict; | |
use warnings; | |
use Getopt::Long; | |
use URI; | |
use Term::ReadKey; | |
use LWP::Debug; | |
use LWP::UserAgent; | |
use Data::Dumper; | |
use SOAP::Lite on_action => sub { "$_[0]$_[1]"; }; | |
import SOAP::Data 'name', 'value'; | |
my ($sp_endpoint, $sp_listid, $sp_domain, $sp_username, $sp_password, $debug); | |
$debug = 0; | |
GetOptions( | |
"endpoint=s" => \$sp_endpoint, | |
"listid=s" => \$sp_listid, | |
"domain=s" => \$sp_domain, | |
"username=s" => \$sp_username, | |
"password=s" => \$sp_password, | |
"debug=s" => \$debug, | |
); | |
$sp_endpoint ||= 'http://host.your.domain.com/path/to/site/_vti_bin/lists.asmx'; | |
$sp_domain ||= URI->new( $sp_endpoint )->host_port; | |
$sp_listid || die "--listid missing\n"; | |
$|=1; | |
$sp_username ||= do { | |
print "Username (DOMAIN\\username): "; | |
ReadLine(0); | |
}; | |
$sp_password ||= do { | |
print STDERR "Password: "; | |
ReadMode('noecho'); | |
my $tmp = ReadLine(0); | |
chomp $tmp; | |
ReadMode('restore'); | |
print STDERR "\n"; | |
$tmp; | |
}; | |
chomp $sp_username; | |
if ($debug) { | |
LWP::Debug::level('+'); | |
SOAP::Lite->import(+trace => 'all'); | |
} | |
my @ua_args = (keep_alive => 1); | |
my @credentials = ($sp_domain, "", $sp_username, $sp_password); | |
my $schema_ua = LWP::UserAgent->new(@ua_args); | |
$schema_ua->credentials(@credentials); | |
my $soap = SOAP::Lite->proxy($sp_endpoint, @ua_args, credentials => \@credentials); | |
$soap->schema->useragent($schema_ua); | |
$soap->uri("http://schemas.microsoft.com/sharepoint/soap/"); | |
my $lists = $soap->GetListCollection(); | |
die(1, $lists->faultstring()) if defined $lists->fault(); | |
# Given a list $title and the list of lists ($lists) - return the $title list ID | |
sub lists_getid { | |
my ($title, $lists) = @_; | |
my @result = $lists->dataof('//GetListCollectionResult/Lists/List'); | |
foreach my $data (@result) { | |
my $attr = $data->attr; | |
return $attr->{ID} if ($attr->{Title} eq $title); | |
} | |
return undef; | |
} | |
# Return all the items in a list | |
sub lists_getitems { | |
my $listid = shift; | |
my $in_listName = name('listName' => $listid); | |
my $in_viewName = name('viewName' => ''); | |
my $in_rowLimit = name('rowLimit' => 99999); | |
my $call = $soap->GetListItems($in_listName, $in_viewName, $in_rowLimit); | |
die($call->faultstring()) if defined $call->fault(); | |
return $call->dataof('//GetListItemsResult/listitems/data/row'); | |
} | |
my $list_id = lists_getid($sp_listid, $lists); | |
my @items = lists_getitems($list_id); | |
# For all of the rows in the list, if the row has an IP (ows_HostIP) and a | |
# hostname (ows_LinkTitle) add it to our collection. | |
# One-to-many IP to hostnames are allowed | |
my $hosts = {}; | |
foreach my $row (@items) { | |
my $attr = $row->attr; | |
next unless $attr->{ows_HostIP}; | |
next unless defined $attr->{ows_LinkTitle}; | |
push @{ $hosts->{ $attr->{ows_HostIP} } }, $attr->{ows_LinkTitle}; | |
} | |
# Method for adding a host/IP to the list | |
sub add_ip { | |
my ($list, $hostname, $ip) = @_; | |
my $field_id = name('Field', 'New')->attr({ Name => 'ID'}); | |
my $field_linktitle = name('Field', $hostname )->attr({ Name => 'Title'}); | |
my $field_something = name('Field', $ip )->attr({ Name => 'HostIP'}); | |
my $method = name('Method', [$field_id, $field_linktitle, $field_something])->attr({ ID => "anything", Cmd => 'New'}); | |
my $batch = name('Batch', \$method); | |
my $in_listName = name('listName' => $list); | |
my $in_updates = name('updates' => \$batch); | |
my $call = $soap->UpdateListItems($in_listName, $in_updates); | |
die($call->faultstring()) if defined $call->fault(); | |
} | |
# Method for updating a row in a list | |
sub alter_id { | |
my ($list, $itemid, $hostname, $ip) = @_; | |
# This is important, as it identifies what you're updating | |
my $field_id = name('Field', $itemid)->attr({ Name => 'ID'}); | |
my $field_linktitle = name('Field', $hostname )->attr({ Name => 'Title'}); | |
# The Cmd == Update bit is important | |
my $method = name('Method', [$field_id, $field_linktitle])->attr({ ID => "anything", Cmd => 'Update'}); | |
my $batch = name('Batch', \$method); | |
my $in_listName = name('listName' => $list); | |
my $in_updates = name('updates' => \$batch); | |
my $call = $soap->UpdateListItems($in_listName, $in_updates); | |
die($call->faultstring()) if defined $call->fault(); | |
} | |
# Actaully output the hosts records (sorted by IP) | |
for my $ip (map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, pack("C4", split /\./, $_) ] } keys %{ $hosts }) { | |
unless ( @{ $hosts->{$ip} } > 0 ) { | |
warn "No hosts for IP $ip\n"; | |
} | |
else { | |
print $ip, " ", join(" ", @{ $hosts->{$ip} }), "\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment