Friday, August 8, 2014

Office365 SharePoint - Rename Multiple Files in Document Library

Unfortunately, Office 365 SharePoint doesn't let you to do too much using the built-in PowerShell cmdlets. Sometimes this trick can also come in handy with On Premise SharePoint installations when you just need a quick way to manipulate files in a library. Using PowerShell commands this is much more complicated.
Last day I ran into an issue (maybe I'll post that later) when I had to rename multiple files in a Document Library that resides on an Office 365 SharePoint instance.

What I did was the following:



Step1 - Add the website to the IE's Trusted Sites


First of all, you have to use Internet Explorer. Open in Explorer mode only works with this browser. Add the website to the trusted site's list then restart the browser. Otherwise it will complain later.


Now browse to your SharePoint Library again.



Step 2 - Open the Library in Explorer


Go to Library -> Open with Explorer



Step 3 - Map the location as a Network Drive


Now that you can see the library in Explorer, you need to grab the URL from the Address bar (ctrl + c) and map a network drive:



Press the ALT + T -> Map Network Drive



Choose a drive letter, paste your path and Finish. You may not want to reconnect the drive at logon.


Now, that you can see your files as a drive you can use your favorite tool to manipulate them.


Step 4 - Use your favorite tool to manipulate the files


I just used cmd to rename all pdf files but you can do much, much more with Total Commander if you have to.



Of course, this method work with SharePoint Server (On Premise) as well.

Thursday, April 17, 2014

Renewing JIRA's the SSL Certificate on Windows

Basically this is JAVA specific stuff.

Environment:


  • Windows Server 2008 R2
  • JIRA Standalone (6.2) (Installed in C:\JIRA)
  • JDK 1.7 (Installed to C:\JDK)
AFAIK this method applies to all JIRA and JAVA/JDK editions.


Step 1: Identifying the JKS (Java KeyStore) file location


This is the file where the certificates used by Tomcat are stored. The JKS file is linked with JIRA in the server.xml file that is located under the JIRA INSTALL DIRECTORY\conf\server.xml (In this example C:\JIRA\conf\server.xml). Open in notepad and search for JKS to find the section we're insterested in. 

SSLEnabled="true" acceptCount="100" clientAuth="false" connectionTimeout="20000" disableUploadTimeout="true" enableLookups="false" keyAlias="tomcat" keystoreFile="C:\JIRA\cert\jira.jks" keystorePass="somepass" keystoreType="JKS" maxHttpHeaderSize="8192" maxSpareThreads="75" maxThreads="150" minSpareThreads="25" port="443" protocol="org.apache.coyote.http11.Http11Protocol" scheme="https" secure="true" sslProtocol="TLS" useBodyEncodingForURI="true" />


Step 2: Creating a CSR


For this you use keytool.exe that is located in your JDK instance's bin directory. You will be asked for the keystore password that can also be found on the xml mentioned earlier. Make sure to mention the -alias parameter with the keyAlias attribute from the settings.xml file.

C:\JDK\bin> keytool -certreq -keystore "C:\JIRA\cert\jira.jks" -alias tomcat

No questions asked, the request will use the same properties as your current certificate. Now copy-paste the CSR from the console and send it to your CA that will issue the certificate for you.


Step 3: Installing the new certificate


Once you got the new certificate save it as a .cer file (I'll save it as C:\JIRA\cert\jira.cer in this example) and open its properties to export *all* the CA certificates from the certification path:




Click on View Certificate -> Details -> Copy to File and export it in the DER encoded binary X.509 format.



After the exports, in this example I'll have 3 certificates to import into the KeyStore file:
jira.cer (the certificate I got from the CA)
ca-root.cer (the first certificate exported in the Certification Path)
ca-intermediary.cer (the second certificate exported in the Certification Path)

So go back to the Command Prompt, you JAVA instance's bin directory and use keytool.exe to import all these certificates. When you're asked if you want to import the certificate, type yes at the console.


C:\JDK\bin>keytool.exe -importcert -keystore "C:\JIRA\cert\jira.jks" -storepass somepass -trustcacerts -alias ca-root -file "C:\JIRA\cert\ca-root.cer" C:\JDK\bin>keytool.exe -importcert -keystore "C:\JIRA\cert\jira.jks" -storepass somepass -trustcacerts -alias ca-intermediate -file "C:\JIRA\cert\ca-intermediate.cer" C:\JDK\bin>keytool.exe -importcert -keystore "C:\JIRA\cert\jira.jks" -storepass somepass -trustcacerts -alias tomcat -file "C:\JIRA\cert\jira.cer"


Restart Tomcat (JIRA) and you're done.

Wednesday, April 9, 2014

Top FREE Cloud Storage Providers - 2014

Short and on subject (as always :).

Did some research on the market and currently these are the top Cloud Storage Providers that offer the Most Free Space and have Desktop and Mobile (iOS, Android) Sync Clients.
Everyone is starting the list with Dropbox but that's outdated offering a shameful of 2GB.

  1. Mega.co.nz - 50 GB
  2. FireDrive - 50 GB
  3. Bitcasa.com - 20 GB (Sync up to 3 devices)
  4. Copy.com - 15 GB (Or you get 20GB if you register from this referral)
  5. Google Drive - 15 GB
  6. 4sync.com - 15 GB
  7. MediaFire.com - 10 GB
  8. Box.com - 10 GB (250 MB max file size)
  9. Microsoft OneDrive - 7 GB

Note - I personally recommend Copy.com, it's a great service. Works almost just like Dropbox but you get a ton of space. You get an additional 5GB for every referred friend.

Although you can scrape up a bunch of free space this way I don't recommend installing more than two sync clients on your computer because it can seriously affect the computers performance.

I will update this list as soon as something interesting comes up.

Additional Resources

  • 5/3/14 - Adding FireDrive to #2 offering a mind-blowing free space of 50GB and no file size limit.

Monday, March 24, 2014

VBoxManage modifyhd Code CO_E_SERVER_EXEC_FAILURE (0x80080005) - Server execution failed

This is a lol one. I tried extending the hard disk of a Virtual Machine and received the following error:

C:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd "E:\Virtual Machines\JIRA\Windows Server 2008.vdi" --resize 40960
VBoxManage.exe: error: Failed to create the VirtualBox object!
VBoxManage.exe: error: Code CO_E_SERVER_EXEC_FAILURE (0x80080005) - Server execution failed (extended info not available)
VBoxManage.exe: error: Most likely, the VirtualBox COM server is not running or failed to start.

The Solution


Do *not* start Command Prompt as admin!

Friday, March 21, 2014

Cannot set unknown member 'CompositeTask.PreserveIncompleteTasks'. HTTP headers received from the server

The problem


Today I encountered a strange issue when trying to publish a basic SharePoint 2013 Workflow that has a Start Task Process action in it.


The error I received was the following:

Cannot set unknown member 'CompositeTask.PreserveIncompleteTasks'. HTTP headers received from the server


Microsoft.Workflow.Client.ActivityValidationException: Workflow XAML failed validation due to the following errors:
Cannot set unknown member 'CompositeTask.PreserveIncompleteTasks'. HTTP headers received from the server - ActivityId: 51341428-f7a1-4856-8303-fcbc699335ea. NodeId: SPSRV. Scope: /SharePoint/default/8f0c9dfe-6f01-499c-a356-a417da9b39b4/53d5e7f1-0360-4909-8997-71eaf26b140d. Client ActivityId : a1627f9c-bdfc-80a3-b6fd-cf246a4e8993. ---> System.Net.WebException: The remote server ret


Solution


Checking the logs didn't provide any useful clue. Digging the net I found a post (linked at the bottom) that suggested re-registering the SharePoint 2013 Workflow Service. So I did that.

Register-SPWorkflowService -SPSite https://portal.mydomain.net -WorkflowHostUri https://spsrv:12290 -Force

Question: Will this command affect my currently running workflows?
Answer: No, all workflows will continue running smoothly, even if they are in progress, paused or waiting for an item to change. Tested.


Resources




Monday, March 17, 2014

SharePoint: Are there any Users currently on the site?

Problem


Ever wondered is there anyone connected to the SharePoint Site before doing an iisreset or a server reboot? Or how much the site is used on a daily basis?


Solution


The Performance Monitor tool is just about perfect for this. You can make a custom console, save it and use later. Or you can collect data over time to have a better overview on the server usage (Data Collector Sets section, not covered in this post).



Below I'll detail step by step how to create a custom MMC Console.

  1. First, start a blank mmc console




  2. Add a Performance Monitor Snap-In






  3. You've got a blank Performance Monitor Console. Now you have to add the Counters.



  4. Click on the green Plus Sign and find the following counters:

    Web Service Category
    - Current Anonymous Users
    - Current Non-Anonymous Users

    At the Instances section you can select a particular website or just _Total.



    I also like to add other helpful counters like CPU Usage, Memory, etc. For more info on counters please consult this blog post.


  5. Go to View -> Customize and remove the clutter




  6. Go to File -> Save As and save the console for later use. There you go.


Obviously, you can use this to monitor any kind of IIS Website like TFS, etc.

Tuesday, March 4, 2014

Updating Permissions on List Items via PowerShell

The following script crawls all document libraries from a path of site and looks for *budget*.xls* and will replace all permissions on the Item with Read.
The script is useful to cut access for a pattern of files.

if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
 Add-PSSnapin Microsoft.SharePoint.PowerShell
}

$site = get-spsite -identity "http://myspportal"

foreach($web in $site.AllWebs)
    {

    if ($web.Url.Contains("http://myspportal/HR/"))     # Look for only under HR
        {

        $Lists = $web.Lists | Where-Object {$_.Title -Like "*Reports*"}   # Pattern to look for in LISTS names
        $roleReadOnly = $web.RoleDefinitions["Read"]

        foreach($list in $lists)
            {
            
             foreach($item in $list.Items | Where-Object {$_.Name -like "*budget*.xls*"})     # Filename pattern is *budget*.xls*
                {
                Write-Host $item.ParentList.ParentWeb.Url+'/'+$item.URL + '      ' + $item.Name
                if ($item.HasUniqueRoleAssignments -eq $false)
                    {
                    $item.BreakRoleInheritance($true);
                    }

                foreach ($ra in $item.RoleAssignments | Where-Object {$_.RoleDefinitionBindings.Name -eq "Contribute" -or $_.RoleDefinitionBindings.Name -eq "Full Control" -or $_.RoleDefinitionBindings.Name -eq "Edit"})
                    {
                        $ra.RoleDefinitionBindings.RemoveAll()
                        $ra.RoleDefinitionBindings.Add($roleReadOnly)
                        $ra.Update()
                    }

                }
            }
        }
    }

Thursday, February 27, 2014

SharePoint 2010 vs 2013 Workflow Inconsistencies

These days I was tearing my hair out. I am rewriting some old workflows on my SharePoint system and can't decide whether to use v 2010 or 2013 workflows. There are definitely some useful features in the 2013 workflows but there are also some very basic features missing.

Here they are:

There is no impersonation step


This is somewhat understandable. Impersonation step in unreliable because when the employee who deployed the workflow leaves the company and the AD user is removed, the workflow will fail to start.


Cannot set permission on items


There is no way to replace permission on items. This was very useful in some cases.


Lookup Field - Additional Fields


Consider having a Lookup field linked to another list that is retrieving some additional columns. For example the Title is the main column, and you also retrieve the ID and Status fields. In 2010 you can work with these additional columns, but in 2013 only the main Lookup column is showing up.

In 2010 Workflow:

In 2013 Workflow:


This is crazy. Yes, you could retrieve the ID as the main column instead, then do a Lookup on the other list in the workflow. But in this case the New Item form shows a dropdown with some numbers instead the lookup field of your choice. Here you can use InfoPath to customize - which is retiring.


There is no Else-If


Serously??
Even the Else branch is missing from the auto-complete.


Wait for field to not equal a value


In 2010 Workflow you have all the options:

In 2013 Workflow there is only the Equal:







Start List/Site Workflow



Via a 2013 WF you can only start a v2010 workflow. Wtf??








That's it for now... I'll update this post once I find some more annoyances.

Thursday, January 9, 2014

Tomcat 7 FindClass org/apache/catalina/startup/Bootstrap failed

Environment

  • Windows Server 2008 R2
  • Tomcat 7 x64
  • jdk1.7.0_45 x64

 Problem


After upgrading from Tomcat 6 to 7 the new Tomcat instance did not want to start up. This is what I saw in the logs:

[2014-01-09 19:08:46] [info]  [ 2516] Commons Daemon procrun (1.0.15.0 64-bit) started
[2014-01-09 19:08:46] [info]  [ 2516] Running 'Tomcat7' Service...
[2014-01-09 19:08:46] [info]  [ 6004] Starting service...
[2014-01-09 19:08:47] [error] [ 6080] FindClass org/apache/catalina/startup/Bootstrap failed
[2014-01-09 19:08:47] [error] [ 6004] Failed to start Java
[2014-01-09 19:08:47] [error] [ 6004] ServiceStart returned 4
[2014-01-09 19:08:47] [info]  [ 2516] Run service finished.
[2014-01-09 19:08:47] [info]  [ 2516] Commons Daemon procrun finished


2014-01-09 19:08:46 Commons Daemon procrun stderr initialized
java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
    at org.apache.catalina.startup.Bootstrap.(Bootstrap.java:60)
Caused by: java.lang.ClassNotFoundException: org.apache.juli.logging.LogFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 1 more
Exception in thread "main" 


All I found on the net was that Java 5 is not compatible with Tomcat 7. But I had the latest Java 7.


Solution


With trial and error I found the solution:

I had to include tomcat-juli.jar also in the Java Classpath!

I opened an administrative Command Prompt and edited the Tomcat instance's Properties

D:\apps\tomcat7\bin> tomcat7w.exe //ES//Tomcat7




Monday, January 6, 2014

Compress Old Files with PowerShell

The Story


The following PowerShell script will compress files that are older than the specified amount of time. It is handy for archiving IIS Logs, SQL Backups, etc.
The script uses 7-zip so you obviously have to have it installed (or the exe copied somewhere). It's using maximum compression which is resource intensive, if you don't want that just remove the "-mx9 -m0=lzma2" parameters.


The Script

$path = "C:\inetpub\logs\LogFiles\"
$mask = "*.log"

$days = 7

$files = dir $path -Recurse -Include $mask | where {($_.LastWriteTime -lt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and ($_.psIsContainer -eq $false)}


ForEach ($file in $files) {

    & "C:\Program Files\7-Zip\7z.exe" u -mx9 -t7z -m0=lzma2 ($file.FullName + ".7z") $file.FullName
    if ($LASTEXITCODE -eq 0) {
        Remove-Item $file
    }

}

Resources