SharePoint: Simple Sample Approach to Autonumber
Below is a formula for a quick and dirty autonumber for lists in SharePoint. There are a variety of ways to generate this field. Some solutions use workflow or external lists, but I prefer this method because of its simplicity.
Note: Because this solution depends on the record's ID column, it generates the autonumber *after* a record has been added, so if you need the autonumber to appear in the "New.." form, this solution is not for you. My project, which required the Request Number to be in "WR-0000" format, was fine with having it generated after the fact.
To create my Request Number, I created a new calculated column, named it Request Number and entered the following formula:
=CONCATENATE("WR-",REPT(0,4-LEN(ID+1)),ID+1)
This formula combines WR- with leading 0's and the ID number that's built into SharePoint lists. The output looks like so:

Thanks to my main SharePoint man, Trevor, for giving me this entire solution. You should start a blog, yo
SharePoint 2010: Use CSS to Auto-expand Calendar Entries
I looked all around the web for a simple solution to auto-expanding events in a monthly Calendar view. Unfortunately, this isn't something that's built-in to SharePoint, so it has to be done using workarounds. There were many solutions suggested on the web, though a majority required file system edits. Hey, no thanks!
Here's what worked for me: I created a new monthly view called Expanded View, set it to default, then fired up SharePoint designer and opened the new view for editing. Per the suggestion found on StackOverflow, I inserted a Content Editor Web Part right above the calendar, then used the split view to find the CEWP and between CDATA[[]], I added
<script type="text/javascript">
_spBodyOnLoadFunctionNames.push('WaitForCalendarToLoad');
function WaitForCalendarToLoad()
{
SP.UI.ApplicationPages.SummaryItemRenderer.prototype.$2u = function ()
{
ULSvSp: ;
if (!this.$1A_1) this.$1A_1 = 100;
return this.$1A_1
}
}
</script>
This works best for calendars that mostly have all-day events. Because hourly events add extra lines to display the hours, this solution may not be the best one for those needing to show calendars packed with hourly events; it's not as streamlined. If anyone has some code for making auto-expanded hourly events look good, I'd love to see it.
PowerShell: Copy-Item -recurse -force Does Not Create Directories when Using Get-ChildItem -include
I recently wrote a PowerShell script which copied documents from a filter to my local hard drive. I chose PowerShell for this task because it was one of the few programs actually allowed on my ultra locked-down workstation (and 'cuz I love it.)
Because I only wanted specific types of files, I gathered the list of documents using get-childitem -recurse -include and then copied the files using copy-item. What I didn't initially realize was that copy-item's -recurse and -force switches are ineffective in my script because 1.) I'm passing the copy-item command one item at a time and 2.) the get-childitem include switch is "best considered a file filter," according to Lee Holmes of Microsoft's PowerShell team..
I got around this by manually creating the directory structure as needed using if (!(test-path($dir))) { mkdir $dir }. The entire script can be found below:
$source = "L:\"
$destination = "C:\docs\"
$since = (Get-date).AddDays(-365)
$includes ="*.doc*","*.pdf","*.xls*","*.ppt*"
$items = get-childitem $source -recurse -include $includes | where-object {$_.LastAccessTime –gt $since}
foreach ($item in $items)
{
$dir = $item.DirectoryName.Replace($source,$destination)
$target = $item.FullName.Replace($source,$destination)
if (!(test-path($dir))) { mkdir $dir }
if (!(test-path($target)))
{
copy-item -path $item.FullName -destination $target -recurse -force
}
}OpenVPN: Update Client DNS Servers on Mac OS X Using the Command Line.
There's a bit of a debate on how best to update your DNS resolver on Mac OS X when connecting to an OpenVPN Server. For whatever reason, even if use DHCP on the VPN server, OS X won't use the assigned DNS server(s). It's been recommended to use scutil, but the scripts are crazy long and I've read the resolver order sometimes gets reset anyway.
The usual route of using /etc/resolv.conf does not work on OS X but specifying DNS servers in your Network Preferences does. If you use public network servers like 8.8.8.8 or 4.2.2.2, you're already set. Move along
But if you rely on DHCP assigned DNS servers, the the script below will do the trick. This script specifies or clears (sets back to DHCP default) the DNS servers on each of the adapters listed in networksetup.
#!/bin/bash
# Set bash delimeter to be line break
IFS=$'\n'
# VPN DNS Server
vpndns='172.20.0.1'
# Get adapter list
adapters=`networksetup -listallnetworkservices |grep -v denotes`
for adapter in $adapters
do
echo updating dns for $adapter
dnssvr=(`networksetup -getdnsservers $adapter`)
if [ $dnssvr != $vpndns ]; then
# set dns server to the vpn dns server
networksetup -setdnsservers $adapter $vpndns
else
# revert back to DHCP assigned DNS Servers
networksetup -setdnsservers $adapter empty
fi
doneAgain, if you already set your DNS servers, your OpenVPN connection will use those. This script is effective for people who use DHCP assigned DNS servers by default and would like to tunnel their DNS requests when connecting to an OpenVPN server.
OS X: Find Network Gateway using the Comand Line
This is a bit more complex than it should be; I was hoping networksetup would make this easier but, alas. Using netstat -nr appears to be the best way to find your gateway from the command line:
netstat -nr | grep '^default' | awk '{ print $2 }'
If you haven't played around with networksetup, I recommend checking out networksetup -getinfo "Airport" and networksetup -listnetworkserviceorder.
PowerShell: Find/Replace Template
Brandon had this in some of his maintenance plan code and I found myself using it a bit so I thought I'd blog about it. Here is a simple script that reads a file (C:\scripts\maintenanceplans\$sqlversion\template.dtsx), replaces certain placeholders (in this case, [SERVERNAME] and [BACKUPPATH]), then writes a new file with that content.
$serverName = "sqlserver1"
$backupPath = "D:\dbbackups"
# Read in the maintenance plan template and replace the place holders
$textTemplate = [IO.File]::ReadAllText(".\maintenanceplans\$sqlVersion\template.dtsx")
$textTemplate = $textTemplate.Replace("[SERVERNAME]","$serverName")
$textTemplate = $textTemplate.Replace("[BACKUPPATH]","$backupPath")
# Write the new package. MUST use UTF8 encoding or it will break.
Set-Content -Encoding utf8 ".\out.dtsx" $packageContents
This particular script writes out XML files. If you are writing a plain text file, remove "-Encoding utf8" and you're set.
iPhone Dev: Base SDK Missing Solved
Someone awesome sent me the code to an iPhone app that he created for RealCajunRecipes.com. I unzipped the file, and opened the project in XCode 4.2. I immediately noticed the upper left hand drop down (what's that called anyway?) said "Base SDK Missing." So I went to all the usual places to change the SDK, I saved it and restarted XCode. Nope, I still encountered the following error when trying to Build my project: error: There is no SDK with the name or path 'iphonesimulator3.1'.
Google searches gave me the same "solution" over and over but none of it worked. Ultimately, I had to go into my projects .xcodeproj directory to edit the file project.pbxproj.
I changed the lines that referenced SDKROOT from SDKROOT = iphonesimulator3.1 to SDKROOT = iphoneos, restarted XCode and successfully built the app.
SharePoint + PowerShell: Batch Import Models, Create ECT’s, Set Permissions
Here is a script that will batch import Models, create associated ECT's, and set permissions for users and admins. Please modify the variables as needed.
# script from netnerds.net
# Make sure the namespace is the same as the namespace in your exported bdcm files
# My $siteURL happens to be the same as my $namespace. That may not be the case for you.
# Do this only on dev machines
# I'm running this on the SharePoint 2010 server so I made my servicecontext localhost
#
# What this does:
# Scans current directory for BDC Export(.bdcm) files
# Creates the External System/Lob and the External Content Types
# Creates External Lists from those ECT's
# Sets the proper permissions
$adminGroup = "DOMAIN\SharePoint Admins"
$userGroup = "DOMAIN\SharePoint Users"
$serviceContext = "http://localhost/"
$nameSpace = "http://sharepoint/"
$SiteUrl = $nameSpace
$bdc = Get-SPBusinessDataCatalogMetadataObject -BdcObjectType Catalog -ServiceContext $serviceContext
$pathtobdcmfiles = Get-Location
$importFiles = Get-Childitem -path $pathtobdcmfiles | Where {$_.extension -eq ".bdcm" -and $_.basename -ne "catalog"}
foreach ($file in $importFiles) {
Import-SPBusinessDataCatalogModel -Path $file.FullName -Identity $bdc -force -ModelsIncluded -PropertiesIncluded -PermissionsIncluded -Verbose
# THIS WHOLE CHUNK COMES FROM: http://gallery.technet.microsoft.com/scriptcenter/82437789-f294-4bcd-8210-a1ba0e081f82/
# IT MAKES THE EXTERNAL LISTS FROM THE MODELS. AWESOME.
$Model = Get-SPBusinessDataCatalogMetadataObject -BdcObjectType Model -Name $file.baseName -ServiceContext $ServiceContext
$ListUrl = "Lists/{0}"
ForEach ($Entity in $Model.AllEntities)
{
$ns = $Entity.Namespace
Write-Host "Entity Namespace : $ns"
$name = $entity.Name
Write-Host "Entity Name : $name"
Write-Host "Looking for MethodInstance specific finder..."
$sf = $Entity.MethodInstances | Where-Object{ $_.MethodInstanceType -eq [Microsoft.BusinessData.MetadataModel.MethodInstanceType]::SpecificFinder }
If($sf -eq $null)
{
Write-Host "Skipping external list creation as Method Instance of Type SpecificFinder was not found in Entity : $name"
break
}
else
{
Write-Host "Creating and Configuring SPListDataSource"
$ds = New-Object -TypeName Microsoft.SharePoint.SPListDataSource
$instanceName = [String]::Empty
ForEach($instance in $entity.LobSystem.LobSystemInstances){$instanceName = $Instance.Name}
$ds.SetProperty("LobSystemInstance", $instanceName)
$ds.SetProperty("EntityNamespace", $ns)
$ds.SetProperty("Entity", $name)
$ds.SetProperty("SpecificFinder", $sf.Name)
$site = $null
Try
{
$site = Get-SPSite -Identity $SiteUrl
$web = $site.OpenWeb()
$web.Lists.Add($Entity.Name, "", [String]::Format($ListUrl, $Entity.Name), $ds);
}
Finally
{
$web.Dispose()
$site.Dispose()
}
}
}
#END CHUNK
}
$claimAdmin = New-SPClaimsPrincipal -Identity $adminGroup -IdentityType WindowsSamAccountName
$claimUsers = New-SPClaimsPrincipal -Identity $userGroup -IdentityType WindowsSamAccountName
Grant-SPBusinessDataCatalogMetadataObject -Identity $bdc -Principal $claimAdmin -Right "Execute,SetPermissions,Edit,SelectableInClients"
Grant-SPBusinessDataCatalogMetadataObject -Identity $bdc -Principal $claimUsers -Right "Execute,Edit,SelectableInClients"
Copy-SPBusinessDataCatalogAclToChildren -MetadataObject $bdc
#Ignore this, its what I wish my namespace was...
#$nameSpace = "http://$env:USERDNSDOMAIN/".toLower()
As they say in the SuSE Linux motd: Have a lot of fun!
SharePoint + PowerShell: Import All BDCM Files in a Directory and Set Permissions
In order to invest as little effort as possible creating and recreating and recreating my External Content Types on my development server, I exported the ECT's then deleted External Content Types, External Systems, and BDC Models. I saved them all in a directory on the SharePoint server, then I placed ImportALLbdcms.ps1 in the same directory and ran it.
$adminGroup = "DOMAIN\SharePoint Admins" #for bdc permissions
$userGroup = "Domain\SharePoint Users"
$serviceContext = "http://localhost/"
$nameSpace = "http://$env:USERDNSDOMAIN/".toLower()
$bdc = Get-SPBusinessDataCatalogMetadataObject -BdcObjectType Catalog -ServiceContext $serviceContext
$pathtobdcmfiles = Get-Location
$importFiles = Get-Childitem -path $pathtobdcmfiles | Where {$_.extension -eq ".bdcm" -and $_.basename -ne "catalog"}
foreach ($file in $importFiles) {
Import-SPBusinessDataCatalogModel -Path $file.FullName -Identity $bdc -force -ModelsIncluded -PropertiesIncluded -PermissionsIncluded -Verbose
write-host $file.fullname
}
$claimAdmin = New-SPClaimsPrincipal -Identity $adminGroup -IdentityType WindowsSamAccountName
$claimUsers = New-SPClaimsPrincipal -Identity $userGrup -IdentityType WindowsSamAccountName
Grant-SPBusinessDataCatalogMetadataObject -Identity $bdc -Principal $claimAdmin -Right "Execute,SetPermissions,Edit,SelectableInClients"
Grant-SPBusinessDataCatalogMetadataObject -Identity $bdc -Principal $claimUsers -Right "Execute,Edit,SelectableInClients"
Copy-SPBusinessDataCatalogAclToChildren -MetadataObject $bdc
Sorry for a junky intro and no conclusion, I've been working 19 hour straight and I'm about exhausted. Anyway, HTHY!
SharePoint 2010 + PowerShell: Export/Import Calendar Items
Today has been miserable. All I wanted to do was import a SharePoint 2007 calendar into SharePoint 2010 to use as sample data for a prototype site. I was caaarraaazzy enough to believe it would be a simple import/export, but no. There's no such thing. Maybe I could use Outlook calendaring or idq files as a medium? No. So I decided to do the good ol "Save this as a template and include content" workaround. Then I followed Tom's awesome instructions on how to hack the SharePoint 2007 template to get SharePoint 2010 to use it.
That worked! It imported over 3000 calendar items, but then the library itself was broken. When I'd make modifications (such as checking the box to make the calendar a resource), it would throw unknown errors IN MY FACE. So I decided I would just create a fresh SharePoint 2010 Calendar, then import the data using a PowerShell script which would just copy list item data from one calendar to another. This should work for almost any list in SharePoint. Here's how I did it, y'all:
First, create a new Calendar using the regular Calendar template. Then, run this script after changing $siteURL, $sourceListName and $destListName to suit your environment.
$siteURL = "http://sharepoint/"
$sourceListName = "Corporate Calendar"
$destListName= "Prototype Calendar"
$site = Get-SPSite $siteURL
$web = $site.RootWeb
$sourceList = $web.Lists[$sourceListName]
$destList = $web.Lists[$destListName]
$columns = $sourceList.Fields;
$sourceItems = $sourceList.GetItems();
foreach($sourceItem in $sourceItems) {
$newItem = $destList.AddItem();
foreach($column in $columns) {
if ($column.ReadOnlyField -eq $False -and $column.InternalName -ne "Attachments") {
$newItem[$($column.InternalName)] = $sourceItem[$($column.InternalName)];
}
}
$newItem.Update();
}
$web.dispose()
$site.dispose()
Note that I didn't include support for attachments at this time; 8 hours after starting on this Copy Calendar Events journey began, I'm just too beat! Perhaps I'll add it later.
Update: My awesome friend Trevor shared this link with me: Create random or demo SharePoint Content with PowerShell Cool.


