Thursday, March 18, 2010
#
I've been extremely fortunate to work at /n software, but after more than 9 years, the time has come for me to say "goodbye". This Friday will be my last day. The people behind the amazing machine that is /n software are great, hard working people, and I'll be a fan for life. Most importantly though, I'm looking forward to new experiences and new challenges. I'll be joining an exciting new online marketing startup in Chapel Hill (more about them later!). My new work will be as a C# developer, but I'll continue to be a presence on Twitter, still talking about the technologies I love and the process of building techie goodness, and I'll continue to blog away about PowerShell, software development, and more!
Update soon!
Wednesday, February 17, 2010
#
Right after you install SP2010 (Foundation or Server), even on a completely updated Windows Server 2008 SP2, when you go to start the SharePoint 2010 Management Shell (the recommended PowerShell interface for working with SharePoint), you get a real ugly looking error:
Exception setting "ThreadOptions": "This property cannot be changed after the Runspace has been opened."
At C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONF
IG\POWERSHELL\Registration\SharePoint.ps1:2 char:48
+ if ($ver.Version.Major -gt 1) {$Host.Runspace. <<<< ThreadOptions = "ReuseTh
read"}
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
To get around this problem, update the Windows Management Framework Core. See KB968930, where you can download updates for various versions of Windows.
There are still Site Template in SharePoint 2010, but they're no longer .STP files. Instead, they're packaged in .WSP files just like web parts and features. No longer is there a "Site Template Gallery", instead there is a "Solutions Gallery".
To create a Site Template, browse to the Site you want to create from. Go to Site Actions –> Site Settings –> Save site as template (under the Site Actions heading). Give your template a name, and don't forget to check the "Include Content" box if you want to include library and list content in the template. This will create a new site template in your Solutions Gallery, which you can then use when creating new sites. You can also download directly from the Solutions Gallery to a .WSP file.
To upload a Site Template to the Solutions Gallery, go to Site Actions –> Site Settings –> Solutions Gallery (under the Galleries heading). On the Solutions tab of the ribbon, click "Upload Solution". Before you close that dialog, you'll need to click "Activate" to activate it if you want your Site Template to appear in the "New Site" dialog later.
To use the Site Template, go to Site Actions –> New Site. You'll find your Site Template in the list of Installed Items, in the All Categories or Blank & Custom filters.
Don't like one of your page layouts on your SharePoint Site? No problem, you can solve this problem quickly and easily using the free SharePoint Designer. It doesn't take any programming, just a couple minor HTML tweaks.
Note: This is different from modifying the master page, which will effect every page on the site. Instead, we'll be detaching the page from the master page, therefore making it unique on the site. This obviously has its cons when its comes to long-term site style.
Here's how a site looks, out of the box:

Notice how the "Right" web part zone is narrow, and the "Left" web part zone takes up the remaining part of the actual page content. I don't like that…its backwards for me. Here's how to change it:
- Inside SharePoint Designer 2010, click "Open Site", type in your URL, and click "Open".

- Click "Edit site home page".

- Now the default.aspx for the page will appear. Areas that define the page layout itself will have a highlighted background color. Those lines cannot be changed unless you enter "Advanced Mode". So first, click the "Advanced Mode" button found on the Home menu (top right of your screen in the ribbon). Now, looking at the HTML of the page, the part I want to change is near the bottom, and is the width of the two main WebPartZones on the page (the "Left" and "Right" Web Part Zones)?
- Finally, just save the site in SharePoint Designer and then close it. When you save, your changes will be written to the SharePoint Server, so the next time you visit your page, it will appear as desired:

Wednesday, January 13, 2010
#
This post is the tenth and last in a series of postings, containing examples of SharePoint WebParts that anybody can build all by themselves. To read all posts in this series, or to get started with the RSSBus WebPart, go here.
#10 - Keep Your SharePoint Calendar Synced with Google
The following is one way you can use to keep your SharePoint Calendar(s) synced up with your Google Calendar. This particular example only syncs in one direction: from Google to SharePoint. It could go the opposite direction, or both, but that's not what I need so that's not what I did. :) As usual, this solution requires that you have the RSSBus Web Part installed. See here for instructions. You'll also need the GoogleOps Connector, which is automatically included with the RSSBus Web Part.

Step one: Logon to SharePoint and browse to your calendar. Under Site Actions, click Edit Page.
Step two: Now, click on "Add a Web Part", and add the RSSBus Web Part to the page. I prefer to drag the Calendar up so that it is on top, and this RSSBus Web Part is just below it. On its edit menu, click Modify Shared Web Part and open the Source Editor.
Step three: Paste in the following RSSBus Web Part template, and click "Apply".
Step four: After you click Apply, you'll need to specify your Google Calendar email and password, the name of the calendar to sync with (ie, "Calendar"), and the number of days you want it to keep synced at a time. Optionally, you can embed these inputs into the script if you want, instead of leaving them as web part properties. To do that, change the rsb:info section of code to this:
<rsb:set attr="email" value="YOUREMAIL" />
<rsb:set attr="password" value="YOURPASSWORD" />
<rsb:set attr="calendar" value="YOURCALENDARNAME" />
<rsb:set attr="days" value="30" />
Now, everytime you view your Calendar page it will automatically be updated with the lastest items from Google Calendar.
See all posts in this series: 10 DIY SharePoint Web Parts.
Browse RSSBus Connectors.
Basic RSSBus Scripting Cheat Sheet.
Tuesday, January 12, 2010
#
Anybody who uses Twitter has heard of auto-follow services for Twitter.
Below is a PowerShell script I used to auto UNfollow. The script goes through the people you're following and eliminates "idle" or "spam" friends. An idle friend is determined by a low friend count or low status count on an account that has been in existance for at least a couple months (configurable). A spam friend is determined by a high friend count but a low follower count (by default, the script uses a 15-1 ratio as the max).
I would appreciate any good tweaks or improvements you might like to share! In particular I wasn't sure how to deal with Twitter's rate limiting (150 get requests per hour). For now I just catch the exception when it occurs and sleep for an hour before resuming.
Technorati Tags:
Twitter,
PowerShell
Tuesday, December 29, 2009
#
Today I saw this on Twitter from Julie Blender (@#juneb_get_help):
Need to reference the "ProgramFiles(x86)" environment variable in #PowerShell? Use ${env:ProgramFiles(x86)}.
I use this in a lot of my scripts, but I want a single variable that contains the right value whether I'm in a 64 bit shell or not. Here's my solution:
First, I have a function in my testing profile called is64bit, that looks like this:
Next, I have a get-programfilesdir function that I call that checks whether or not I'm in a 64 bit shell or not and returns the appropriate program files environment variable (ie, if I'm running on a 64 bit machine it will return "C:\Program Files (x86)", but if I'm running on a 32 bit machine it will return "C:\Program Files". If I'm running in a 32 or 64 bit shell on a 64 bit machine, it will always return "C:\Program Files (x86)".
Technorati Tags:
PowerShell
GeeksWithBlogs.net and other SubText Users:
If you are trying to create a new blog post, and you get the following error:
Input string was not in a correct format. at
System.Text.StringBuilder.FormatError()
at System.Text.StringBuilder.AppendFormat(IFormatProvider provider,
String format, Object[] args)
at Subtext.Framework.Util.KeyWords.Scan(String source, String oldValue,
String newValue, Boolean isFormat, Boolean onlyFirstMatch)
at Subtext.Framework.Util.KeyWords.Format(Entry entry)
at Subtext.Framework.Data.DatabaseObjectProvider.FormatEntry(Entry e,
Boolean UseKeyWords)
at Subtext.Framework.Data.DatabaseObjectProvider.Create(Entry entry,
Int32[] categoryIds)
at Subtext.Framework.Entries.Create(Entry entry)
at Subtext.Framework.XmlRpc.MetaWeblog.PostContent(String username,
String password, Post& post, Boolean publish, PostType postType)
The problem has been fixed. It was repoted by Joe Pruitt and fixed by Phil Haack not too long ago. It was happening for Joe (and me) when attempting to submit a post containing curly braces AND having keywords set up in SubText. No doubt both Joe and me had this problem due to posting powershell and C# code snippets.
If you can't get the update yet, you can always just remove your keyword definitions from SubText. Thats what I did. :P
Here are a few one-liners that use NetCmdlets. Some of these I've blogged about before, some are new. Let me know if you have questions, which ones you find useful, or how you altered these to suit your own needs.
- Send email to a list of recipient addresses:
import-csv users.csv | % { send-email -to $_.email -from lance@nsoftware.com -subject "Important Email" –message "Hello World!" -server 10.0.1.1 }
- Show the access control list for a specific Exchange folder:
get-imap -server $mymailserver -cred $mycred -folder INBOX.RESUMES –acl
- Add look and read permissions on an Exchange folder, for a list of accounts pulled from a CSV file:
import-csv users.csv | % { set-imap -server -acluser $_.username $mymailserver -cred $mycred -folder INBOX.RESUMES –acl “lr” }
- Sync system time with an Internet time server:
get-time -server clock.psu.edu –set
To remotely sync the time on a set of computers:
import-csv computers.csv | % { Invoke-Command -computerName $_.computer -cred $mycred -scriptblock { get-time -server clock.psu.edu –set } }
- Delete all emails from an Exchange folder that match a certain criteria. For example, delete all emails from alf@email.com:
get-imap -server $mailserver –cred $mycred | ? {$_.FromEmail -eq alff@email.com} | %{ set-imap -server $mailserver –cred $mycred-message $_.Id -delete }
- Update Twitter status from PowerShell:
get-http –url "http://twitter.com/statuses/update.xml" –cred $mycred -variablename status -variablevalue "Tweeting with NetCmdlets!"
- A test-path that works over FTP, FTPS (SSL), and SFTP (SSH) connections:
get-ftp -server $remoteserver –cred $mycred -path /remote/path/to/checkfor*
Don't forget the *. Also, to use SSL or SSH just add an –ssl or –ssh parameter.
- List disabled user accounts in Active Directory (or any other LDAP server):
get-ldap -server $ad -cred $mycred -dn dc=yourdc -searchscope wholesubtree
-search "(&(objectclass=user)(objectclass=person)(company=*)(userAccountControl:1.2.840.113556.1.4.803:=2))"
- List Active Directory groups and their members:
get-ldap -server testman -cred $mycred -dn dc=NS2 -searchscope wholesubtree -search "(&(objectclass=group)(cn=*admin*))" | select ResultDN, member
- Display the last initialization time (e.g. last reboot time) of all discoverable SNMP agents on a network:
import-csv computers.csv | % { get-snmp -agent $_.computer -oid sysUpTime.0 | %{([datetime]::Now).AddSeconds(-($_.OIDValue/100))} }
Not mentioned here: data conversion (Yenc, QP, UUencoding, MD5, SHA1, base64, etc), DNS, News Groups (NNTP/UseNet), POP mail, RSS feeds, Amazon S3, Syslog, TFTP, TraceRoute, SNMP Traps, UDP, WebDAV, whois, Rexec/Rshell/Telnet, Zip files, sending IMs (Jabber/GoogleTalk/XMPP), sending text messages and pages, ping, and more.
Tuesday, December 08, 2009
#
A while back I posted about how to mark a script parameter as required in PowerShell. Shortly afterwards, there was some chatter on it that I think makes it worthwhile to add another post on the subject of PowerShell script parameters.
Let’s say you have the question: “Can I do <X> with a parameter?”
The answer is probably “Yes”. :)
Jim and an anonymous emailer both asked:
Is there any way you can specify a parameter based on the value of another parameter?
The answer is yes. You can put pretty much any expression in the default evaluator of the parameter definition. For example:
In the above example, if –switchparam is specified in the command, the $user parameter default expression will evaluate to true and prompt the user for a user name.
Technorati Tags:
PowerShell