Friday, November 19, 2010

Donuts v. Bagels

I'm not much of a breakfast guy.  I'm lucky if I get a ClifBar with my morning coffee.  But I enjoy a bagel or donut if given the opportunity.  But here is what I want to know:

If everybody slices a bagel in half, why is only one side coated with toppings?  I.e. shouldn't there be schtuff (e.g. poppyseeds) on BOTH sides?  I can understand with a donut as you eat the thing whole.

Somebody address this market opportunity!

Tuesday, November 2, 2010

Increasing the Maximum File Upload Size in WSS v3/MOSS 2007


So there are three related issues when it comes to trying to allow larger files to be upload to a SharePoint WSS v3 or MOSS 2007 system:

1    1)      Several settings that specify the maximum file size allowed for uploading. We’ll call these settings “Max File Upload Size” settings though the actual property/attribute/setting label may be different in each area you’ll configure. Details are below….
2    2)      Several settings that specify the maximum timeout period (usually in seconds) for either the upload period or the http session.  We’ll call these settings the “timeout” settings though the actual property/attribute/setting label may be different in each area you’ll configure. Details are below….
3    3)      Several settings that are related to the SharePoint site/document indexer for the search shared service provider.  WE’ll call these settings “search crawler” settings though the actual property/attribute/setting label may be different in each area you’ll configure. Details are below….

The relationship between these items is as follows:  the bigger the document/file that you want to upload, the longer it will take, especially for users on low-bandwidth connections.  First, to control how much stuff can be shoved into the SharePoint server, WSS3/MOSS2007 (and 2010, too!) ship with caps on the uploadable size.  When we raise that value we increase the odds that some users will appear to the server to have “gone missing” while uploading large (i.e. slowly) files.  Thus the need to raise the timeout settings.  Also, because of the long lags during file uploads, the user’s security authentication may expire during the time they wait for the file to upload.  Increasing the security validation period can prevent forcing them to login again to see the result of their upload attempt.  Obviously there are security ramifications for changing this (at the Web Application’s zone. Note that one could forego these timeout config changes until/if users start complaining about failed uploads.  The (minor) ramifications of these changes to timeout settings are beyond the scope of this doc so for now we are just going to assume it’s easier to be proactive and do the timeout settings at the same time as the max file upload size setting mods, but do note that the timeout setting is optional until users have problems with the upload of the now allowed larger limit.  Finally, there is typically much desire for uploaded documents to be crawled by the SharePoint Search indexer so documents can be located by users using the search tools in SharePoint.  But just as there are problems introduced by allowing big files to be uploaded, similar problems are introduced by not putting some sort of cap on the size of a file that the crawler/indexer will try to “chew.”  16MB is the limit out of the box for WSS3/MOSS20007.  Often times (e.g. video file uploads, CAD drawings), it is not necessary or desired to raise this limit. But if the documents are text based, you may want to raise this limit to allow the data in the file beyond the 16MB point to be indexed.  I have had problems with raising the value though.  Let me know if you get it to work. J  For now, I have ended up leaving it at the default value and been ok with the note that gets put in the ShPt log file about a too large file being unable to be indexed.

All the changes we are going to make can easily be rolled back AS LONG AS YOU MAKE BACKUPS OF THE ITEMS PRIOR TO MODIFYING THEM – i.e. create a copy of *.config files and rename them (e.g. “Web.Config” copied to become “Web-ORIG as of yyyy-dd-mm hhmm.configOLD”), backup a registry node to a reg file prior to making mods, record ShPt settings in the Central Admin or SSP Search GUI with screenshots stored in a WordPad file.  Also be aware that there are typically SEVERAL Web.config files on a SharePoint server AND there is a difference between a Web.config and an Application.config file.  You may need to modify several Web.Config files and the exact path cannot be provided as it changes depending on how the ShPt server has been configured.  Ergo, when you see a path that mentions a virtual directory (e.g.) you must do the translating for your server AND make sure you alter the proper virtual directory for the ShPt site(s) you  are making the mods for.  Go slow, take notes of before/after and THINK!!!! I.e. the ass you save may be your own.

Max File Upload Size (MFUS) limit mods:

1    1)      First, calculate the value in bytes the size you want to raise the limit to.  E.g. 500MB = (500 * 1028 * 1024) = 524288000 Bytes.
2    2)      Open up Central Admin and for each Web application that contains the site(s) you are increasing the MFUS limit, open the “Web Application General  Settings” page. Increase the “Maximum Upload Size” setting to your desired MFUS limit in MB.
3    3)      Using the integer amount in bytes for your new MUFS limit, add the maxAllowedContentLength attribute and value in the Web.config for each virtual directory that maps to a site, zone, or Web application (extended or base WA) in SharePoint, locate the Web.config file.   A typical (EXAMPLE) path for such a Web.config looks like:
a.      C:\inetpub\wwwroot\wss\VirtualDirectories\80
b.     C:\inetpub\wwwroot\wss\VirtualDirectories\11001
e.g. this... web-ORIG as of 2010-08-02.config


               </configSections>
               <SharePoint>



 

…gets turned into this...


  </configSections>
  <system.webServer>
       <security>
  <requestFiltering>
  <requestLimits maxAllowedContentLength="524288000"/>
  </requestFiltering>
  </security>
  </system.webServer>
  <SharePoint>

Note that if doing timeout setting mods, you will return to this file (but I’m breaking this into functional sections for clarity of what affects what).
4    4)      If you are running on Windows Server 2008 (i.e. Internet Information Server 7.0) or R2 (i.e. IIS7.5), the following (optional) proactive change may  also need to be made.
a.      Add the same value for the maxAllowedContentLength attribute IF IT EXISTS.  The attribute, its element (or even the whole section ) may be missing. If not, you can create the attribute or make it look like <requestLimits maxAllowedContentLength="524288000"/> for the element and attribute (and any missing parent elements as shown in the example above) to the application.config file, located at:
                                                    i.     %windir%\system32\inetsrv\config\applicationhost.config

Timeout mods:

1    1)      If desired, to prevent user’s from having to re-authenticate after a long file upload, increase the time that a logged-in user is allowed to sit “idle” by going to ShPt Central Admin and on the appropriate Web Application(s)’s “Web Application General Settings” page (i.e. http://YourSharePointServer[:CAport]/_admin/vsgeneralsettings.aspx ) and increasing the “Web Page Security Validation” settings “Security validation expires’ value. Default is 30 minutes.  60 has generally worked for us in the past.
2    2)      for each  Web site (aka Virtual Server) in IIS Manager , change the connection timout limit (in Seconds) as appropriate for you new MFUS limit. E.g. default "120" (i.e. 2 minutes) to "3600" (i.e. 60 minutes). I.e. …
a.      Click Start, point to All Programs, point to Administrative Tools, and then click Internet Information Services (IIS) Manager.
b.      Right-click the virtual server that you want to configure, and then click Properties.
c.      Click the Web Site tab. Under Connections, type the number of seconds that you want in the Connection time-out box, and then click OK.

3    3)      Modify the “layouts” Web.config (i.e.  "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\web.config" by changing/adding the executionTimeout attribute and a max allowed value of 999999 in the Web.config’s httpRuntime element like so...


  <location path="upload.aspx">
  <system.web>
  <httpRuntime maxRequestLength="2097151" />
    </system.web>
  </location>

to this...

  <location path="upload.aspx"> 
  <system.web> 
    <httpRuntime executionTimeout="999999" maxRequestLength="2097151" /> 
    </system.web> 
 </location>

Note that the value in maxRequestLength will probably be different.  This value seems to be overridden by the <system.webServer> <security> <requestFiltering> <requestLimits maxRequestLength<  attribute’s value.  If you don’t find that to be true, you can change it to match your MUFS limit but IN Kilobytes, NOT Bytes. E.g.  524288000 Bytes  = 512000KB.

4    4)      add the executionTimeout attribute and a max allowed value of 999999 in the Web.config for each virtual directory that maps to a site, zone, or Web application (extended or base WA) in SharePoint, locate the Web.config file.   A typical (EXAMPLE) path for such a Web.config looks like:
a.      C:\inetpub\wwwroot\wss\VirtualDirectories\80
b.     C:\inetpub\wwwroot\wss\VirtualDirectories\11001
e.g. this...


<httpRuntime maxRequestLength="51200" />

becomes this...

<httpRuntime executionTimeout="999999" maxRequestLength="51200" />

Note that the value in maxRequestLength will probably be different.  This value seems to be overridden by the    attribute’s value.  If you don’t find that to be true, you can change it to match your MUFS limit but IN Kilobytes, NOT Bytes. E.g.  524288000 Bytes  = 512000KB.

Friday, February 19, 2010

The $500 Denon audio cable

http://www.amazon.com/Denon-AKDL1-Dedicated-Link-Cable/product-reviews/B000I1X6PM/ref=cm_cr_pr_helpful?ie=UTF8&showViewpoints=0

Ah, yes, yet another example that some of us out there are making TOO MUCH DAMN MONEY &/or are too stupid to be allowed to use the Internet alone!!.  Oh, wait, I should say some HAVE too much money as they surely aren't working for their income....are they? OMFG!

Sunday, February 14, 2010

Prepare files for upload to SharePoint

'______________________________________________________________________________________________
'++++++++++++++++++++ File Digester for SharePoint Document Library Loading ++++++++++++++++++++
'++++++++++++++++++++ File Digester for SharePoint Document Library Loading ++++++++++++++++++++
'++++++++++++++++++++ File Digester for SharePoint Document Library Loading ++++++++++++++++++++
'+
'+
'+ +++++ Usage Summary +++++
'+ Allows a source root folder to be specified (in CONFIG Section below) and have all files and sub-folders' files
'+ to be crawled. Every file found is checked for:
'+ 1) SharePoint-disallowed characters in the filename.
'+ 2) barred filetype extensions (i.e. the OoTB ones for SharePoint)
'+ 3) filename length longer than 128 characters (i.e. SP's max allowed).
'+
'+ You must specify the destination folder for the "cleaned-upu" files to be COPIED to. I.e. the original's are left untouched.
'+ You can also specify if you want the outputted copies to be broken into subfolders.
'+ If you do so, you need to specify what total size you want to aim for for each sub-folder.
'+
'+ See Deron for more details if need be.
'+
'+ '+++++ Revision History +++++
'+
'+ 2010-02-13 (21:45MDT) Deron S. Dilger Original Version
'+
'+
'+
'______________________________________________________________________________________________




Option Explicit

Dim intDebugLevel
Dim DisallowedCharArray
Dim SubstitutionChar
Dim DisallowedExtensionsArray
Dim SubstitutionExtension
Dim strSourceRootPath
Dim strDestRootPath
Dim CurrentPath
Dim strCurrentDestPath
Dim CopyResult
Dim intDocIDStart
Dim intFilesFoundCounter
Dim intFoldersFoundCounter
Dim intBadCharsCounted
Dim intBadExtCounted
Dim intTooLongNamesCounted
Dim MsgOut
Dim CurrentPrefix
Dim intMaxFileCount
Dim blnOutputDestSubs
Dim MaxOutputFolderSizeMB
Dim objShell
Dim objFSO
Dim objLogTS
Dim intUserResponse
Dim objSrcRootFolder
Dim objDestRootFolder

Dim FileDigestionLogPath
Dim aItem 'the object (file or folder) found by the recursive FSO crawl

'--- Set counters to zero
intFilesFoundCounter = 0
intFoldersFoundCounter = 0
intBadCharsCounted = 0
intBadExtCounted = 0
intTooLongNamesCounted = 0

'______________________________________________________________________________________________
'++++++++++ CONFIGURATION AREA ++++++++++++++++++++++++++++++
'++++++++++ CONFIGURATION AREA ++++++++++++++++++++++++++++++
'++++++++++ CONFIGURATION AREA ++++++++++++++++++++++++++++++

intDebugLevel = 0 '0=off, 1 = low verbosity, 2 = medium, 3 = high

'--- SharePoint doesn't allow the following characters in files uploaded to docLib.../ \ : * ? " < > | # { } % ~ &
'--- but since WinXP doesn't allow the following characters \/:*?"<>|
'--- we'll only check for # {}%~&
DisallowedCharArray = Array("#", Chr(9), "{", "}", "*", "~", "&")
SubstitutionChar = "^"

'---
DisallowedExtensionsArray = LoadDisallowedExtensionsArray() 'see the function to modify which extensions are corrected
SubstitutionExtension = ".XYZ"

'strSourceRootPath = "C:\PRRIP Library Digester"
strSourceRootPath = "C:\PRRIP Files"
strDestRootPath = "C:\PRRIP Library Digested For SP Uploader"

FileDigestionLogPath = strDestRootPath & "\^^^FileDigestion.log"

intDocIDStart = 0 'this will be incremented the first time into the loop so start one less than the desired first ID
intMaxFileCount = 5000
blnOutputDestSubs = True
MaxOutputFolderSizeMB = 180

'______________________________________________________________________________________________
'++++++++++ CODE AREA ++++++++++++++++++++++++++++++
'++++++++++ CODE AREA ++++++++++++++++++++++++++++++
'++++++++++ CODE AREA ++++++++++++++++++++++++++++++

intFilesFoundCounter = 0
intFoldersFoundCounter = 0

Set objShell = WScript.CreateObject ("WScript.Shell")
'### Set objFolder = objShell.Namespace (folderPath)
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objSrcRootFolder = objFSO.GetFolder(strSourceRootPath)

'--- See if our output/destination folder exists and if not, create it.
If objFSO.FolderExists(strDestRootPath) Then
intUserResponse = objShell.PopUp("Destination Folder" & vbCrLf & "'" & strDestRootPath & "'" & vbCrLf & " already exists!", ,"Proceed with Pre-Existing Destination Folder?", 52)
If intUserResponse = 7 Then
WScript.Quit
Else
Set objDestRootFolder = objFSO.GetFolder(strDestRootPath)
End If
Else
Set objDestRootFolder = objFSO.CreateFolder(strDestRootPath)
End If
'--- set our current output/destination folder as the root destination folder to start
strCurrentDestPath = strDestRootPath

'--- create the output log to record our file digesting moves into
If objFSO.FileExists(FileDigestionLogPath) Then
intUserResponse = objShell.PopUp("Digestion Log" & vbCrLf & "'" & FileDigestionLogPath & "'" & vbCrLf & " already exists!", ,"Append to Pre-Existing File Digestion Log?", 52)
If intUserResponse = 7 Then
WScript.Quit
End If
End If
Set objLogTS = objFSO.OpenTextFile(FileDigestionLogPath, 8, True)

objLogTS.WriteBlankLines(3)
objLogTS.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
objLogTS.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
objLogTS.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
objLogTS.WriteLine("File Digestion Started at " & Now)
objLogTS.WriteBlankLines(3)
objLogTS.WriteLine("!X! in a new filename indicates an intentionally truncated filename.")
objLogTS.WriteLine("^ in a new filename indicates an intentionally substituted character in the new filename.")
objLogTS.WriteLine("a double-extension filename indicates an intentionally added 'safe' extension for the filename.")
objLogTS.WriteLine("Field header row follows after three blank lines.....")
objLogTS.WriteBlankLines(3)
'--- Write the field header line to the log
objLogTS.WriteLine("DocID" & Chr(9) & "OutputPath" & Chr(9) & "OriginalPathAndName" & Chr(9) & "NewFileName")


'--- create the first sub-folder in the output folder if subs are desired
If blnOutputDestSubs Then
strCurrentDestPath = strCurrentDestPath & "\" & CStr(intDocIDStart+1)
'### WScript.echo("Check for existance of " & strCurrentDestPath & vbcrlf & " is:" & CStr(objFSO.FolderExists(strCurrentDestPath)))
If Not objFSO.FolderExists(strCurrentDestPath) Then
objFSO.CreateFolder(strCurrentDestPath)
End If
End If


'--- enter the recursive function to crawl the source folder's subfolders and rename/relocate all found files.
getInfo(objSrcRootFolder)

'--- build the final msg

MsgOut = "File Digestion Ended at " & Now & vbCrLf
MsgOut = MsgOut & "All done!" & vbCrLf & intFilesFoundCounter & " Files found in root folder plus " & intFoldersFoundCounter & " subfolders." & vbCrLf
MsgOut = MsgOut & "Bad Characters Removed = " & intBadCharsCounted & vbCrLf
MsgOut = MsgOut & "Bad Extensions Stuffed = " & intBadExtCounted & vbCrLf
MsgOut = MsgOut & "Overly-long Filenames Chopped = " & intTooLongNamesCounted & vbCrLf

WScript.Echo(MsgOut)

objLogTS.WriteBlankLines(3)
objLogTS.WriteLine(MsgOut)
objLogTS.Close
WScript.Quit

'+++ Some brainscribbles....
'### objFSO.MoveFile origFullName, newFullName

'______________________________________________________________________________________________

'++++++++++ FUNCTIONS AREA ++++++++++++++++++++++++++++++
'++++++++++ FUNCTIONS AREA ++++++++++++++++++++++++++++++
'++++++++++ FUNCTIONS AREA ++++++++++++++++++++++++++++++

Function LoadDisallowedExtensionsArray
'### .List of disallowed file extensions:
Dim TempArray
TempArray = Array(_
".ade",_
".adp",_
".app",_
".asa",_
".ash",_
".asm",_
".asp",_
".bas",_
".bat",_
".cdx",_
".cer",_
".chm",_
".class",_
".cmd",_
".cnt",_
".com",_
".config",_
".cpl",_
".crt",_
".csh",_
".der",_
".dll",_
".exe",_
".fxp",_
".gadget",_
".hlp",_
".hpj",_
".hta",_
".htr",_
".htw",_
".ida",_
".idc",_
".idq",_
".ins",_
".isp",_
".its",_
".jse",_
".ksh",_
".lnk",_
".mad",_
".maf",_
".mag",_
".mam",_
".maq",_
".mar",_
".mas",_
".mat",_
".mau",_
".mav",_
".maw",_
".mda",_
".mdb",_
".mde",_
".mdt",_
".mdw",_
".mdz",_
".msc",_
".msh",_
".msh1",_
".msh1xml",_
".msh2",_
".msh2xml",_
".mshxml",_
".msi",_
".msp",_
".mst",_
".ops",_
".pcd",_
".pif",_
".prf",_
".prg",_
".printer",_
".pst",_
".reg",_
".rem",_
".scf",_
".scr",_
".sct",_
".shb",_
".shs",_
".shtm",_
".shtml",_
".soap",_
".stm",_
".url",_
".vb",_
".vbe",_
".vbs",_
".ws",_
".wsc",_
".wsf",_
".wsh"_
)
LoadDisallowedExtensionsArray = TempArray
End Function
'______________________________________________________________________________________________


Function getInfo(pCurrentDir)
CurrentPath = objFSO.GetAbsolutePathName(pCurrentDir)
For Each aItem In pCurrentDir.Files
intFilesFoundCounter = intFilesFoundCounter + 1
CurrentPrefix = CStr(intFilesFoundCounter + intDocIDStart) & "-"
Dim OrigFilename
Dim NewFilename
OrigFileName = CStr(aItem.Name)
NewFileName = OrigFileName
NewFileName = CleanUpBadChars(NewFileName)
NewFileName = ChangeBadExtensions(NewFileName)
NewFileName = ChopNameLength(NewFileName, CurrentPrefix)

'--- debug info output?
If intDebugLevel > 1 Then
WScript.Echo ("File Found = " & intFilesFoundCounter & vbCrLf &_
"Current Dir: " & CurrentPath & vbCrLf & "Current File: " &_
aItem.Name & vbCrLf & "Relocated File's filename will be: " & NewFileName)
End If


'--- Move the files
CopyResult = CopySPSafeFilename((CurrentPath & "\" & OrigFileName), NewFileName)

'--- write the file modification info to the log
objLogTS.WriteLine(intFilesFoundCounter + intDocIDStart & Chr(9) & CurrentPath & Chr(9) & OrigFileName & Chr(9) & NewFileName)

If (intFilesFoundCounter > intMaxFileCount) Or (intFilesFoundCounter = intMaxFileCount) Then
Exit For
End If
Next

For Each aItem In pCurrentDir.SubFolders
intFoldersFoundCounter = intFoldersFoundCounter + 1

'--- if we haven't hit our stoppoint for files, keep digging.
If (intFilesFoundCounter > intMaxFileCount) Or (intFilesFoundCounter = intMaxFileCount) Then
Exit For
Else
If intDebugLevel > 1 Then
WScript.Echo ("Found sub-folder #: " & intFoldersFoundCounter & vbCrLF &_
"We are recursively passing thru sub-folder" & vbCrLf & aItem.Name)
End If
getInfo(aItem)
End If

Next
End Function
'______________________________________________________________________________________________


Function CleanUpBadChars(FileToCheck)
'--- SharePoint doesn't allow the following characters in files uploaded to docLib.../ \ : * ? " < > | # { } % ~ &
'--- but since WinXP doesn't allow the following characters \/:*?"<>|
'--- we'll only check for # {}%~&
'--- and the filename has to be shorter than 128 characters

'---count how many substitution chars we already have (by subtracting from the counter will use for bad ones below
Dim intBCCL
Dim NewBCCount
For intBCCL = 1 To Len(FileToCheck)
If Mid(FileToCheck, intBCCL, 1) = SubstitutionChar Then
NewBCCount = NewBCCount - 1
End If
Next

'--- now loop through the array of disallowed characters and replace any that are found in the filename
Dim NameCheckLoopCounter
For NameCheckLoopCounter = LBound(DisallowedCharArray) To UBound(DisallowedCharArray)
If intDebugLevel > 1 Then
WScript.Echo ("Checking " & vbCrLf & FileToCheck & vbCrLf & "for " & DisallowedCharArray(NameCheckLoopCounter))
End If
FileToCheck = Replace(FileToCheck, DisallowedCharArray(NameCheckLoopCounter), SubstitutionChar, 1)
Next

'---count how many bad chars we replaced
For intBCCL = 1 To Len(FileToCheck)
If Mid(FileToCheck, intBCCL, 1) = SubstitutionChar Then
NewBCCount = NewBCCount + 1
End If
Next
intBadCharsCounted = intBadCharsCounted + NewBCCount

CleanUpBadChars = FileToCheck
End Function
'______________________________________________________________________________________________


Function ChangeBadExtensions(FileToCheck)
'--- SharePoint blocks file uploads OoTB for files with certain extensions.
'--- and the filename has to be shorter than 128 characters
Dim NameCheckLoopCounter
For NameCheckLoopCounter = LBound(DisallowedExtensionsArray) To UBound(DisallowedExtensionsArray)
If intDebugLevel > 3 Then
WScript.Echo ("Checking " & vbCrLf & FileToCheck & vbCrLf & "for " & DisallowedExtensionsArray(NameCheckLoopCounter))
End If
'FileToCheck = Replace(FileToCheck, DisallowedExtensionsArray(NameCheckLoopCounter), SubstitutionExtension, 1)
If Right(FileToCheck, Len(DisallowedExtensionsArray(NameCheckLoopCounter))) = DisallowedExtensionsArray(NameCheckLoopCounter) Then
'--- Use the following equation to REPLACE the bad extension...
'FileToCheck = Left(FileToCheck, (Len(FileToCheck) - Len(DisallowedExtensionsArray(NameCheckLoopCounter)))) & SubstitutionExtension
'--- or use the following equation to tack the substitution extension on the end.
FileToCheck = FileToCheck & SubstitutionExtension
intBadExtCounted = intBadExtCounted + 1
End If
Next
ChangeBadExtensions = FileToCheck
End Function
'______________________________________________________________________________________________


Function ChopNameLength(FileToCheck, pCurrentPrefix)
If Len(FiletoCheck) > (128-Len(pCurrentPrefix)) Then
FileToCheck = "!X!" & Right(FileToCheck,((128-Len(pCurrentPrefix))-3) )
intTooLongNamesCounted = intTooLongNamesCounted + 1
End If
ChopNameLength = pCurrentPrefix & FileToCheck
End Function
'______________________________________________________________________________________________


Function CopySPSafeFilename(pOrigFPath, pNewFName)
Dim objCurrentOutputFolder
Dim strCalcDestFilePath

If blnOutputDestSubs Then
Set objCurrentOutputFolder = objFSO.GetFolder(strCurrentDestPath)
'### WScript.Echo("size of " & strCurrentDestPath & " in MB is: " & (objCurrentOutputFolder.Size / 1048576 ) )
If (objCurrentOutputFolder.Size / 1048576) > MaxOutputFolderSizeMB Then 'math of output folder size if for MegaBytes,
'###If (objCurrentOutputFolder.Size / 1024) > MaxOutputFolderSizeMB Then 'math of output folder size if for KILOBytes, not MB (for testing)
'create a new folder and change workingoutputpath
strCurrentDestPath = strDestRootPath & "\" & CStr(intFilesFoundCounter + intDocIDStart)
'### WScript.echo("Check for existance of " & strCurrentDestPath & vbcrlf & " is:" & CStr(objFSO.FolderExists(strCurrentDestPath)))
If Not objFSO.FolderExists(strCurrentDestPath) Then
objFSO.CreateFolder(strCurrentDestPath)
End If
End If
End If

strCalcDestFilePath = strCurrentDestPath & "\" & pNewFName

If intDebugLevel > 0 Then
WScript.Echo("Moving......" & vbCrLf & pOrigFPath & vbCrLf & "To" & vbCrLf & strCalcDestFilePath)
End If


objFSO.CopyFile pOrigFPath, strCalcDestFilePath, False
CopySPSafeFilename = 0
End Function

Scroll the Office 2007 Word Ribbon

Doh! I just realized you can scroll through the Office 2007 ribbon's tabs by putting your cursor anywhere in the ribbon and rolling your mousewheel. Cool!

Monday, February 8, 2010

How to modify a SharePoint _Hidden Site Column

Putting aside the debate (for now) of whether or not you should modify native (aka out-of-the-box) Site Columns in SharePoint (WSS v3.0 / MOSS 2007), here is a way to easily modify site columns that are in the _Hidden Site Column group. <Std. Disclaimer> If you don't understand what this is about, don't risk doing this.</Std.Disclaimer>:


First get to an admin page that shows you the Site Column. You can do this by going to Site Settings > Site Content Type Gallery and click on a Site Content Type that includes the _Hidden Site Column you want to tweak:


Here is a partial view of the Site Content Type Gallery. We are going to click on the "Document" CT so we can modify the _Hidden Site Column "Name."





Note in the following view (it's hard to see, though) that the "Name" site column is NOT a link but "Title" site column is a link to its modify page.



I.e. If we click on the "Title" column's link, we get to this page, which in turn has a link to edit the site column:





If we clicked on that link it takes us to the edit page for the site column:



Now look at the URL for the "Change Site Content Type Column: Document" page:

http://MyMOSSSite/_layouts/ManageContentTypeField.aspx?ctype=0x0101&Field=Title&Fid=%7Bfa564e0f%2D0c70%2D4ab9%2Db863%2D0177e6ddd247%7D

AH!! Lookie there, a field name and GUID in the querystring. So now we just need the field ID for the Name field that the SharePoint GUI is refusing to render a link for. Well, let's look at the source for this page (where the "Columns" section is described):





WSS uses the field GUID as the id so there is the GUID for the "Name" site column -

So now we can do some substition...

The "Title" Site Column's (field) ID=fa564e0f-0c70-4ab9-b863-0177e6ddd247

The "Name" Site Column's (field) ID=8553196d-ec8d-4564-9861-3dbe931050c8

and looking at the link for the "Title" column's editing page...

ManageContentTypeField.aspx?ctype=0x0101&Field=Title&Fid=%7Bfa564e0f%2D0c70%2D4ab9%2Db863%2D0177e6ddd247%7D


So let's hack our way to the "Name" S.C. field "Manage" page using the "Name" S.C.'s GUID:

ManageContentTypeField.aspx?ctype=0x0101&Field=Title&Fid=%7B8553196d-ec8d-4564-9861-3dbe931050c8%7D

which we should clean up to have the dashes in the GUID HTML encoded as %2D to get...

ManageContentTypeField.aspx?ctype=0x0101&Field=Title&Fid=%7B8553196dec8d%2D4564%2D9861%2D3dbe931050c8%7D


Which for the full URL works out to be:

http://MyMOSSSite/_layouts/ManageContentTypeField.aspx?ctype=0x0101&Field=Title&Fid=%7B8553196d%2Dec8d%2D4564%2D9861%2D3dbe931050c8%7D

Which when requested against our SharePoint site gets us:



And from there we can click that edit link to get the page to edit the _Hidden site column "Name":



Insert evil Gene-e-Us laugh here.

Warning: Do NOT change the group or column name without potentially really hosing up your WSS/MOSS site. For this example I was changing the "Description" value for the "Name" field.


If you mess up and rename an out-of-the-box site column and try to change it back, you'll get a warning that prevents you from doing so. If you muck that up, see this KB article: http://support.microsoft.com/kb/923589


If a content type that contains the site column you want to modify is not listed in the Site Content Type Gallery, you may need to drill into the list of columns via a list that uses that content type. For example, the "Event" content type is _Hidden but you can get to it by opening up a calendar list's list settings:




Here is a site that has a full list of the SharePoint ID's for a more direct route:

http://www.aarebrot.net/site/index.php/sitedefinitions/20-sharepointcolumnfieldids



Monday, January 18, 2010

Lessons Learned on SQL Server Instances and Ports

While working on a SQL 2008 install and problems encountered when a second instance was added, some questions came up about how SQL uses ports and allow remote access - especially when a second instance is added to a host computer. Here is the summary:

1) SQL Server 2005/2008 Express, Eval, Developer all install their instances (root OR follow-on) remote access turned OFF by default. References:
http://support.microsoft.com/kb/914277 and http://www.databasejournal.com/features/mssql/article.php/3692831/SQL-Server-2005-Express-Edition---Part-4---Surface-Area-Configration.htm )

2) SQL Server instances supplemental to the initial (aka "root") instance will use Dynamic port assignment for its "listening" port.

3) The default listening port for the initial instance of SQL Server is 1433 EXCEPT for Express which uses dynamic port assignment for ALL its instances by default.

4) The default listening port for additional instances is "dynamic" for all versions.

5) Because of the differences in how SQL Server installs and seems to modify Windows Firewall for the machine SQL is installed on, DSD-Best-Practices is to follow these steps (assuming your goals want remote access to the SQL Server AND you are allowed to make these mods):


a) Install the SQL Instances you want.

b) Use the (2005) "SQL Server Surface Configuration" / (2008) "SQL Server Configuration" program to enable remote client access to the SQL Server. (For 2008 details see: http://msdn.microsoft.com/en-us/library/dd857537(VS.85).aspx note that for 2005 it's done a bit different using the Surface Config tool)

c) Use the (2005) "SQL Server Surface Configuration" / (2008) "SQL Server Configuration" program to specify a (different!) set/static port for each instance (e.g. 1433 for the root instance 2433 for the next instance). (Restart the changed instances to put this into effect).

d) Create a rule to open the machines (Windows) firewall for the ports used for all SQL instances.

e) Test access from a remote machine.

6) The SQL Server Browser Service acts as sort of a proxy server or DNS server on a machine with more than one SQL Server instance. It handles attempts of SQL client's trying to find/reach a SQL Server (instance) by listening on port 1433 (on the server the SQL Server instances are on) and bouncing the requests to the actual port that one of the instances is really answering on. Ergo, on some items (System data source name wizard) you shouldn't expect to see or enter the instance name for a SQL Server. For example, if you have a machine named MySQLServer and the root instance is "MySQLServer" and the second instance is "MySQLServer\IamNumTwo" then you will only see "MySQLServer" in the dropdown.

7) SQL Server Browser Service Reference:
http://msdn.microsoft.com/en-us/library/ms181087.aspx