Recent Custom STSADM Extensions Bug Fixes
For those that follow me on twitter (http://twitter.com/glapointe) you probably already know about these fixes but I’ll try to provide more details here. While I was waiting to start my new job (see my previous post) I decided to take a look at a few of the STSADM commands that I built and fix some things that’s been nagging me for a while. The one I spent the most time on was the gl-convertsubsitetositecollection command and more specifically its partner the gl-repairsitecollectionimportedfromsubsite command.
This command is undoubtedly my most popular command – it’s corresponding blog post is consistently the top requested post on my blog every week. The problem is that I had some direct access database calls in the code which never really set well with me – it violated everything I always tell people – never hit the database directly. The reason for the code was due to two issues: the ContentType field of the master page gallery was getting incorrectly set to a Text type instead of a Choice type and there was no way via the API to change this; discussion lists were getting flattened and there was no way via the API to change this without recreating each item (copy/move operation) which messes up historical/audit information.
There are two things that enabled me to get rid of this DB access code: I’m smarter than I was 2 years ago when I originally wrote the code and SP2 came out. Using code that I wrote for copying lists I was able to simply export the original source master page gallery and import it on top of the target gallery thus forcing the content type field to be fixed. I also found that, in every case I tested, activating the PublishingResources feature now fixes the list (I believe this is the result of SP2 but I’ve not had time to confirm specifically). Also, I removed some code to deal with an earlier bug that was resulting in items being put in arbitrary locations (under the wrong folder) so now discussion list items are correctly imported and not flattened.
So, what does all this mean – if you are not running SP2 then most everything with these commands should work just fine for you but I can’t guarantee everything I’m accounting for will be fixed (particularly discussion lists) – so if you plan on using these commands I strongly recommend you deploy SP2. I also added some additional logging and removed the unnecessary site template related parameters.
Another command that I “fixed” was the gl-createsiteindb command. This one never really sat well with me because I was using reflection to call an internal method in order to pass the target database in – it just seemed like there had to be a way to do this without using reflection. Turns out there was but for whatever reason I just missed it (maybe it’s new with an update or something or maybe I just brain farted). Once you get the SPContentDatabase object you can simply use the Sites property which returns an SPSiteCollection object and then call it’s Add method to add the site to the database – seems so obvious now. Anyways, the code has been updated to use this approach thus avoiding the use of reflection.
The following remaining commands also had some minor fixes done:
- gl-copylistsecurity: Fixed issues for list items (document libraries were not affected) where the target items was being located via the file name property (SPListItem.Name) which was not necessarily set for a generic list. I now first try the FileLeafRef field and if that fails then I use the index of the item in the list.
- gl-importaudiences: The XML file that I was outputting was reversing the value of the SearchString and ReplaceString attributes.
- gl-copycontenttypes: If the document template pointed to an existing document outside the current web the code now correctly copies the value of the document template property without attempting to copy the document itself (previously it would ignore the property if it couldn’t access the file).
- gl-replacefieldvalues: I was previously checking the document out, making the change, and checking the document back in. For various reasons I’ve decided to not attempt to check the document out and instead simply call SystemUpdate to save the changes. I went back and forth on this and would be curious to get peoples thoughts – is it better to have a separate version for each change or leave it as I’ve got it now where no version history is generated?
I’ve not yet updated the documentation for all of these commands but I will attempt do so this week.
New STSADM Commands and Parameters with SharePoint 2007 SP2
I was working on getting SP2 installed so that I could write this post and then I saw that my buddy Todd Klindt beat me to the punch: http://www.toddklindt.com/blog/Lists/Posts/Post.aspx?List=56f96349%2D3bb6%2D4087%2D94f4%2D7f95ff4ca81f&ID=127. But, as Todd only listed the new commands I figured I’d continue with what I was planning which was to show the commands and the new parameters added to existing commands.
To do this I threw together a quick PowerShell script which parses the output of running “stsadm -help” and then calls the help for each of the commands listed, saving the results to a file. I did this for my MOSS 2007 with the IU (Infrastructure Update) installed (my baseline), installed SP2, and then ran the script again. I then used Beyond Compare (great tool) to compare the two files. I’ll start as Todd did, with the new commands (in no particular order):
New Commands
enumallwebs
This command is interesting because it doesn't take in an URL like the enumsubwebs command does (note that Todd references an enumwebs command - he's referring to enumsubwebs). Instead it takes a database name and optional database server. So what's going to happen is that the command will look at the database provided and dump out all the site collections in that database along with every web within that site collection. Here’s the help for the command:
stsadm.exe -o enumallwebs -databasename <database name> [-databaseserver <database server name>]Running the command for one of my databases produces the following results:
<Sites Count="1"><Site Id="f26a9beb-6a70-470e-82b1-4c3f6b34b19a" OwnerLogin="SPDEV\spadmin" InSiteMap="True"><Webs Count="6"><Web Id="93f63c3a-25b9-49d1-a315-2cbcf0b30614" Url="/" LanguageId="1033" TemplateName="SPS#0" TemplateId="20" /><Web Id="36f63321-d475-4786-adcf-4d43cfd3eb32" Url="/Docs" LanguageId="1033" TemplateName="BDR#0" TemplateId="7" /><Web Id="f0106227-339a-48a8-80f4-f9feeef9b840" Url="/News" LanguageId="1033" TemplateName="SPSNHOME#0" TemplateId="33" /><Web Id="1db29e75-2e73-4453-a517-a2b657a80680" Url="/Reports" LanguageId="1033" TemplateName="SPSREPORTCENTER#0" TemplateId="38" /><Web Id="51bf7973-c692-45f6-a5d8-81fa682cce42" Url="/SearchCenter" LanguageId="1033" TemplateName="SRCHCEN#0" TemplateId="50" /><Web Id="a4e50ce6-a527-4269-a590-45f78ea7bf30" Url="/SiteDirectory" LanguageId="1033" TemplateName="SPSSITES#0" TemplateId="34" /></Webs></Site></Sites>Pay attention to the results above because the information provided can be used to help delete orphaned site collections using the updated deletesite command (see below for details).
exportipfsadminobjects
If you deploy custom InfoPath Forms you might be interested in this command - Export InfoPath Forms Services Admin Objects. Running this command will create a CAB file containing all your deployed objects. If you deployed the objects via a Feature then they will not be exported. As Todd points out, there is no corresponding import but as the output is just a CAB file you can easily crack it open and use it manually re-add any of your objects. Here’s the help for the command:
stsadm -o exportipfsadminobjects -filename <path to file>
forcedeletelist
This isn’t actually a new command - it’s name change for the previously incorrectly named forcedeleteweb - you’ll notice that forcedeleteweb no longer exists.
listqueryprocessoroptions
This command is used to identify the current search query processor options. The command itself isn’t very useful as a standalone but rather to help when using the setqueryprocessoroptions (shown below) command. Here’s the help for the command (see http://technet.microsoft.com/en-us/library/dd789568.aspx for more details):
stsadm -o listqueryprocessoroptions -ssp <ssp name>Running the command in my VM environment shows the following:
C:\>stsadm -o listqueryprocessoroptions -ssp SSP1 securitytrimmingcachesize 10000 securitytrimmingmultiplier <default> nearduplicatemultiplier <default> joinmultiplier 10 sdidjoinmultiplier <default>
preupgradecheck
This is perhaps one of the coolest new commands as it helps to give us some insight as to what is going to be coming with the next version, albeit not much in the grand scheme but hey, anything is helpful. You can find more information here: http://technet.microsoft.com/en-us/library/dd793605.aspx. Here’s the help for the command:
stsadm.exe -o preupgradecheck [ -rulefiles <rule files delimited by comma or semicolon.> ] [ -listrulefiles ] [ -localonly ] The preupgrade checker does not perform any repairs, but instead only checks for issues and outputs the list of issues and possible remedies to the issues.Running this command in my single server VM environment produces the fo
C:\>stsadm -o preupgradecheck Processing configuration file: OssPreUpgradeCheck.xml SearchContentSourcesInfo... Information Only SearchInfo... Information Only Processing configuration file: WssPreUpgradeCheck.xml ServerInfo... Information Only FarmInfo... Information Only UpgradeTypes... Information Only SiteDefinitionInfo... Information Only LanguagePackInfo... Information Only FeatureInfo... Information Only AamUrls... Information Only LargeList... Information Only CustomListViewInfo... Passed CustomFieldTypeInfo... Information Only CustomWorkflowActionsFileInfo... Passed ModifiedWebConfigWorkflowAuthorizedTypesInfo... Information Only ModifiedWorkflowActionsFileInfo... Passed DisabledWorkFlowsInfo... Passed OSPrerequisite... Passed WindowsInternalDatabaseMigration... Passed WindowsInternalDatabaseSite... Passed MissingWebConfig... Passed ReadOnlyDatabase... Passed InvalidDatabaseSchema... Passed ContentOrphan... Passed SiteOrphan... Passed PendingUpgrade... Passed InvalidServiceAccount... Passed InvalidHostName... Passed SPSearchInfo... Information Only Operation completed successfully. Please review the results at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Logs\PreUpgradeCheck-20090501-105935-359.htm.
The report that it generates is also very useful - I’d recommend running this guy and saving off the report somewhere even if you are not currently thinking of upgrading - it lists all your details about your topology, Features installed, web applications, databases, site definitions installed, custom field types that won’t be upgraded (note that there are some ootb ones), etc., etc., etc.
setqueryprocessoroptions
This is the sister command for the listqueryprocessoroptions command. You can use this command to change the values identified by the list command. The command is detailed here: http://technet.microsoft.com/en-us/library/dd789632.aspx. Here’s the help for the command:
stsadm -o setqueryprocessoroptions -ssp <ssp name> [-securitytrimmingcachesize <security trimming cache size>] [-securitytrimmingmultiplier <security trimming overfetch multiplier>] [-nearduplicatemultiplier <duplicate removal overfetch multiplier>] [-joinmultiplier <join discard overfetch multiplier>] [-sdidjoinmultiplier <missing security descriptor overfetch multiplier>]
variationsfixuptool
If you’re doing any kind of variations work then you should be very interested in this tool. It basically does what my gl-fixvariationrelationships command does which is to repair the relationships between sibling pages in your various labels. The command is detailed here: http://technet.microsoft.com/en-us/library/dd789658.aspx. Here’s the help for the command:
stsadm -o variationsfixuptool -url <absolute web URL> [-recurse] [-label <label to fix or spawn>] [-fix] [-scan] [-spawn] [-showrunningjobs]
New Parameters
So we’ve gone through all the new commands, no lets look at the commands that have been updated with new parameters.
backup
The backup command has been updated to include two new parameters: nositelock and force. The nositelock parameter is specific to site collection backups and was added to mimic earlier behavior of not locking the site collection during a backup. I don’t recommend you use this behavior but it might be useful if you have scripts that are already using the setsitelock command to make the database read-only (the backup stores the lock state so doing a restore could end up with the wrong state if you are setting the lock then doing your backup). Details about the issue can be found here: http://support.microsoft.com/default.aspx/kb/967568.
The force parameter is specific to doing catastrophic backups and is used to ignore the disk space check.
deletesite
The deletesite command introduces 4 new parameters: force, siteid, databasename, and databaseserver. These new parameters are specific to deleting orphaned site collections. These parameters are detailed here: http://technet.microsoft.com/en-us/library/cc288016.aspx.
The key thing is that when adding a content database to an existing web application it is possible that the content database contains a site collection that is mapped to an existing site collection. This results in the site collection being orphaned (not site mapped). You can use the new enumallwebs command (detailed above) to get the list of site collections in a database along with the whether the site is site mapped (InSiteMap attribute) along with the site ID.
deleteweb
Like the deletesite command the deleteweb command introduces 4 new parameters: force, webid, databasename, and databaseserver. These commands serve the same purpose as those for the deletesite command but with regards to subsites instead of site collections. The details for the command are here: http://technet.microsoft.com/en-us/library/cc287710.aspx. Note that the wording in this document is a bit confusing as they seem to interchange site, subsite, web, and site collection for the same thing - I think the document fell victim to some copy and paste.
getproperty/setproperty
The getproperty and setproperty commands introduce three new parameters (or properties): change-log-expiration-enabled, change-log-retention-period, event-log-retention-period.
The first property, change-log-expiration-enabled (detailed here: http://technet.microsoft.com/en-us/library/cc263361.aspx), specifies whether change logs are deleted after the time span defined by the change-log-retention-period.
The second property, change-log-retention-period (detailed here: http://technet.microsoft.com/en-us/library/cc261921.aspx), specifies the amount of time to preserve the change logs. This property is equivalent to the “Change Log” setting on the Web Application General Settings page.
The third property, event-log-retention-period (I couldn’t actually find any documentation on this one), obviously has to do with how long the event logs are retained but what I can’t figure out is what event logs? I did find that the property maps to the SPWebApplication’s EventLogRetentionPeriod property but as that property is also not documented it didn’t really tell me much.
osearch
The osearch command introduces one new parameter: reprovisionindex. I couldn’t find anything about this parameter other than a short paragraph from the SP2 changes list. Essentially this is just useful if you have more than one SSP as the following describes:
“In a farm with multiple SSPs, the administrators can use the new stsadm command to re-initialize the query servers for one of the SSPs while the other SSP continues to serve the query request. The command is the following, where SharedServices1 is the name of the SSP whose query servers are being re-initialized: "stsadm -o osearch -reprovisionindex -ssp SharedServices1"”
updatefarmcredentials
The updatefarmcredentials command introduces one new parameter: resume. I couldn’t find any documentation about this parameter but think of it as a force parameter (that’s how it’s used internally). I suspect this was added to get around various encryption errors that people get now and again when using this command. If anyone has more information on this please share
![]()
Backup/Restore Now Supported Between Farms (via April CU)
I just saw a very exciting blog post from Stefan Goßner regarding the April 2009 Cumulative Update (CU) - with this update you can now use backup and restore to move site collections between farms: http://blogs.technet.com/stefan_gossner/archive/2009/05/01/red-is-green-up-is-down-and-the-unsupported-suddenly-becomes-supported.aspx.
So first off, yes there is an April CU even though SP2 just came out a couple of days ago (think about it - SP2 has been cooked for a while but they’ve been testing, writing SDK docs, etc., etc., - in the meantime the team has continued working on new updates). I strongly recommend that you install SP2 before you install this update!
So what’s the change that makes it supported now? Anyone ever have to use my gl-fixpublishingpagespagelayouturl command to fix page layouts that were absolute and pointing to the wrong server? Well, this is the primary fix that Microsoft has made so that site collections (specifically those that use the publishing features) can be moved across farms. Note that I suspect that my command will still have lots of uses (I need to do some disassembling to figure out the specific change - good chance my command won’t be needed anymore but I doubt it).
Some more information about the April CU can be found here: http://blogs.msdn.com/joerg_sinemus/archive/2009/05/01/should-i-install-sp2-and-or-april-cu.aspx
PowerShell CmdLet Name Changes
Ever since I released my PowerShell CmdLets I’ve been unhappy about my choice to use the -gl in the name of the cmdlet. I felt it would be useful for numerous reasons but I didn’t like that it “broke the rules” of cmdlet naming conventions. And then Microsoft announced, via the PowerShell team blog, that some code will be added to V2 to enforce the prescribed naming conventions. You can find the post here: http://blogs.msdn.com/powershell/archive/2009/04/16/increasing-visibility-of-cmdlet-design-guidelines.aspx. The specific piece of concern is that a warning will be generated if more than one hyphen is present in the cmdlet name.
As a result of this enforcement of the guidance and in anticipation of eventually having a V2 version of my cmdlets I decided to go ahead and pull the -gl suffix from my cmdlet names. I thought about keeping an alias in place so that existing scripts would not break but in the end decided that there was probably a pretty small user base actually using my them and that it would be better to just get people to make the move. I will try and update my existing PowerShell posts to account for the removal of the name (guess it’s a good thing I’m behind on documenting most of them
).
SPDisposeCheck Released
This is a must have! If you do any kind of SharePoint development then you should strongly consider downloading the recently released SPDisposeCheck tool: http://blogs.msdn.com/pandrew/archive/2009/01/29/spdisposecheck-v1-3-1-is-released.aspx. This tool analyzes your assemblies and helps to identify potential memory leaks. I should note that you need to truly evaluate each result because not every item should be considered a show stopper – you need to understand the various dispose patterns and should use this tool as a quick way to check for things that your (or your peers) might have missed.
And, in case anyone is wondering – yes, I have run this tool against my extensions and here are the results:
---------------------------------------------------------- Total Found: 0 ---------------------------------------------------------- Modules Checked: 1 ---------------------------------------------------------- Lapointe.SharePoint.STSADM.Commands.dll ---------------------------------------------------------- Modules Ignored: 0 ---------------------------------------------------------- ---------------------------------------------------------- Methods Ignored: 0 ---------------------------------------------------------- |
Sometimes I know what I’m doing
Running it against my PowerShell cmdlets results in 6 issues found but they are all false positives due to the fact that I’m returning an SPSite and SPWeb object via a base property/method and I’m explicitly expecting the caller to dispose of these objects. Here’s an example of that output:
ID: SPDisposeCheckID_110
Module: Lapointe.SharePoint.PowerShell.Commands.dll
Method: Lapointe.SharePoint.PowerShell.Commands.Proxies.SPSiteInfo.GetSPObject
Statement: CS$1$0000 := new Microsoft.SharePoint.SPSite(this.{Lapointe.SharePoint.PowerShell.Commands.Proxies.SPSiteInfo} get_ID())
Source: W:\work\Lapointe.SharePoint.PowerShell.Commands\Lapointe.SharePoint.PowerShell.Commands\Proxies\SPSiteInfo.cs
Line: 98
Notes: NOTE: This instance was returned from the method and can likely be ignored as long as the type is disposed in the caller.
SPDisposeCheck will automatically determine if the instance was disposed in the calling method
Disposable type not disposed: Microsoft.SharePoint.SPSite
***This may be a false positive depending on how the type was created or if it is disposed outside the current scope
More Information: http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx#SPDisposeCheckID_110
|
If you have similar false positives in your code you can have the tool ignore these by adding the SPDisposeCheckIgnore attribute to your method or property. Here’s a snippet from the documentation included with the tool:
Accepting an Issue
If you have investigated a reported issue and are satisfied that it doesn’t represent a problem you can have it ignored by the tool. To do this add the declaration of the SPDisposeCheckIgnore attribute to the method where the error is shown and specify the error to ignore. You also need to add the declaration for SPDisposeCheckIgnore to your project. You can safely change the namespace of SPDisposeCheckIgnore to match your project to avoid additional using statements in your source files. Here is an example, which you can see in the SPDisposeExamples project.[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_110, "Don't want to do it")]
WSS Build of My STSADM Extensions
If you're a WSS v3 user this will hopefully make you happy - I've reworked my custom extensions so that there is now a WSS specific build. This means that you can download the source and debug in a pure WSS environment and you will also no longer be plagued by commands being available but not working either at all (because they're just for MOSS) or only partially because I had one small MOSS specific feature that's not necessary for WSS.
If you look at the top of my blog (or in the right nav) you will now see an additional download option for a WSS WSP file. If you're a WSS only environment you'll want to install this (make sure you retract any previous installation of my commands - because this file is a different name it won't force you to do so but you will definitely want to).
When you deploy the extensions there will now be three files for the MOSS install and two files for the WSS install:
- Lapointe.SharePoint.STSADM.Commands.dll (MOSS and WSS - goes in the GAC)
- stsadmcommands.moss.lapointe.xml (MOSS only)
- stsadmcommands.wss.lapointe.xml (MOSS and WSS)
If you download the source you will see that the original "Debug" and "Release" configurations have been replaced with those specific to either MOSS or WSS:
All I'm doing is using a simple conditional compilation symbol, "MOSS", which I use to wrap all MOSS specific code within. I'm hoping to find some time to also rework the index of commands that I have which is really just a jumbled mess. This should make it easier to see what's available.
I hope people will find this rework beneficial and, as always, your feedback is most welcome and appreciated!
Content Deployment QFE Pack Now Available
I just saw a couple of posts from AC and Spence regarding the release of the Content Deployment QFE Pack:
I won't reiterate what they've already done a good job stating. My point of this post is to ask those who have previously commented on my blog about issues with the CD to please post any follow-up information you may have if you end up deploying the QFE and re-run the scenario that caused the errors you experienced. The most popular commands I've got are all related to those that use the content deployment API and they are the ones with the most issues that I simply can't do anything about so any feedback folks can provide would be greatly appreciated.
Breaking Change to My Extensions
If you've been using my extensions for a while there's a good chance that you have one or more scripts written that use the extensions. If that's the case then my apologies for this particular change - to prevent name clashes with Microsoft and other stsadm developers that are out there I've decided to bite the bullet and prefix all of my commands with "gl-". This is something that I should have been doing all along and I highly encourage anyone developing their own extensions to do something similar.
If you just don't want to take the time to rework all your scripts to use the new names then you can always do a simple search and replace on the stsadmcommands.lapointes.xml file and just remove the "gl-" thus undoing the change. To make this easier I've decided to not rename the remainder of the command (so for the adduser2 command, for example, I wanted to change it to "gl-adduser" but I decided to leave it as "gl-adduser2" so as to make it easier for those that just really don't like my initials).
This change will also make it easier for administrators to identify these custom commands as just that, custom - you'll also be able to list all of the commands by using the following command:
C:\>stsadm -help | find "gl-"
If you're using my sample install script I've uploaded an updated version of it so if you haven't changed anything other than the variables file then you should be able to just download the updated copy.
Again - I apologize for the inconvenience but hopefully you'll agree that this is a good change and will help to get this little hobby of mine into a more professional and community friendly state.
Namespace and Filename Changes (plus 5 new commands)
I've just pushed out a new build which renames all the files and namespaces. If you download this latest build you will have to uninstall the previous build if previously installed. To uninstall delete the stsadmcommands.edfinancial.xml file from the "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG" folder. Also delete the Edfinancial.SharePoint.STSADM.Commands.dll file from the bin folder (under the above mentioned config folder - assuming you copied to this location). You'll also want to remove the dll from the GAC. The new filenames are "Lapointe.SharePoint.STSADM.Commands.dll" and "stsadmcommands.lapointe.xml". You can find these in the Package folder (note that I'm now building the Debug and Release version so you can pick which you want to use). Install these the same as you did before (GAC the dll and copy the xml file to the ...\12\Config folder). Note that this build contains 5 new commands that I've not yet documented:
- gl-movesite - works the way you would expect the renamesite command to work without the limitation of being restricted to host header sites only)
- gl-sitewelcomepage - allows you to set the welcome page of a site
- gl-applytheme - sets the theme to a site (note that upgrade2 was updated to use this functionality so that themes can be reset when upgrading)
- gl-retargetgroupedlistingswebpart - works effectively the same as the gl-retargetcontentquerywebpart but is specific to addressing issues I had with grouped listings to being set right post upgrade
- gl-enumwelcomepages - this was just a helper command that I created to list all the welcome pages (after upgrade some sites had the welcome page set to UpgLandingPgRedir.aspx when it should have been set to Default.aspx and I needed a way to identify all of them)