May 11

Find Large Folders with Powershell v2

I was recently looking for a ‘poor man’ version of Treesize so I could quickly determine an unusually large log file on a server.  Powershell came to the rescue, but there is a little more work to be done with the script or it crashes out Powershell during execution for me.

 The below is from the script center


# ---------------------------------------------------------
# ScriptingGamesBeginnerEvent8_PS1.ps1
# ed wilson, msft 8/21/2009
# PS1 version of HSG-08-19-09 http://bit.ly/1d8Rww
#
# ---------------------------------------------------------
Param(
[string]$path = "c:\fso",
[int]$first = 5
)# end param
# *** Function Here ***

function Get-DirSize ($path){

BEGIN {}

PROCESS{
$size = 0
$folders = @()

foreach ($file in (Get-ChildItem $path -Force -ea SilentlyContinue)) {
if ($file.PSIsContainer) {
$subfolders = @(Get-DirSize $file.FullName)
$size += $subfolders[-1].Size
$folders += $subfolders
} else {
$size += $file.Length
}
}

$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Folder `
-Value (Get-Item $path).FullName
$object | Add-Member -MemberType NoteProperty -Name Size -Value $size
$folders += $object
Write-Output $folders
}

END {}
} # end function Get-DirSize

Function Get-FormattedNumber($size)
{
IF($size -ge 1GB)
{
“{0:n2}” -f ($size / 1GB) + ” GigaBytes”
}
ELSEIF($size -ge 1MB)
{
“{0:n2}” -f ($size / 1MB) + ” MegaBytes”
}
ELSE
{
“{0:n2}” -f ($size / 1KB) + ” KiloBytes”
}
} #end function Get-FormattedNumber

# *** Entry Point to Script ***

if(-not(Test-Path -Path $path))
{
Write-Host -ForegroundColor red “Unable to locate $path”
Help $MyInvocation.InvocationName -full
exit
}
Get-DirSize -path $path |
Sort-Object -Property size -Descending |
Select-Object -Property folder, size -First $first |
Format-Table -Property Folder,
@{ Label=”Size of Folder” ; Expression = {Get-FormattedNumber($_.size)} }

May 09

Package Branching AppV 4.6 SP1

For anyone working through AppV sequencing, creating a test environment, or secondary environment for whatever reason is slightly different from what was covered in my MDOP course.

On that course Tim Mangan’s website was mentioned repeatedly.  Here is a link to his nice rundown on package branching.

In particular, the <WORKINGDIR> bug needs attention when branching.

  • Starting with a clean sequencer, copy the existing package to the desktop.
  • Start the sequencer to update this package, selecting “Add A New Application”. Even though we are not actually adding a new application, this provides access to all steps in the wizard.
  • We select custom install, and once in monitoring mode we make the customizations (rather than install anything).
  • After Installation mode and Configuration mode are completed, we select the customize option so that we can edit the applications.
  • Each Application must be edited. In each case we:
    • Edit the Application Name field to be unique. Not only does this solve the server and client uniqueness issue, it also changes the name of the shortcut when the virtual application is published. Thus the shortcuts will appear side-by-side in the user start-menu if a single user gets both packages published to them. Choosing a different name that is clear is important!
    • Edit the OSD Filename field to be unique.
  • After the streaming page, we select to continue modifying the package. In the “package editor” (the un-named multi-tab interface), we do the following:
    • On the Properties Tab page, change the Package Name.
    • On the Deployment page, change the Path field to match the Package Name. The Path field is the name of the folder we will save the branched package to. Technically it need not change but it is best to do so.
    • We select “File->Save As” from the menu. In that dialog:
      • We create the folder we named in the Path Field previously, and change to that folder.
      • Being paranoid, we check that filename has changed to the new package filename. It will be if we changed the Package Name field on the Properties Tab page.
      • We check the “Save as New Package” checkbox. This gets us a unique Package Guid and new OSD guids in each of the OSD files.
      • We change the Package Root Directory field. Although I allow long names for the Package Root Directory for initial sequences, I like to keep branch package names to the 8.3 compliant format (only because I haven’t verified that Microsoft makes the “short name” version of this folder properly when branching).
      • Being really paranoid, we check that the Package Name field also changed. Again, it will be already changed.
    • Check the WORKINGDIR of each OSD file and amend as necessary

May 08

Overwriting a SQL Database on a Busy instance

When restoring a database to a busy instance, you may find that one or two users have logged on to the application and created a SQL connection.  This will prevent you from being able to restore the database.

If you host dozens of databases, it is impracticle to sift through sp_who or sp_who2 to find or kill the connection.

This post does a good job of using a temporary table for the job.  however, I found that with SQL 2008, there was an extra column being returned, so I have pasted below my modified version.

 


CREATE TABLE #sp_who2 

(SPID INT,

Status VARCHAR(1000) NULL,

Login SYSNAME NULL,

HostName SYSNAME NULL,

BlkBy SYSNAME NULL,

DBName SYSNAME NULL,

Command VARCHAR(1000) NULL,

CPUTime INT NULL,

DiskIO INT NULL,

LastBatch VARCHAR(1000) NULL,

ProgramName VARCHAR(1000) NULL,

SPID2 INT,

REQUESTID INT)

GO

INSERT INTO #sp_who2
EXEC sp_who2

GO

SELECT *
FROM #sp_who2

WHERE DBName = ‘YourDB’

GO

DROP TABLE #sp_who2

GO

 

Mar 28

add a new request URL mapping – Project Server Playbook Backup Error

I had the below error when trying to use the Project Server 2010 playbook to backup our configuration.

…if the url should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application

The error is misleading, because it’s suggesting an alternate access mapping may need to be created.  This was not the case for me.

After reading this post I found my issue was that the account was not in the Farm Administrators group.

Also, if you use an environment with secondary logins for elevated priviledges, this coupled with UAC can make accessing your Project Server playbook URL tricky.  One way to go about connecting to the server is to run a cmd as administrator, then perform a runas with your other account in that prompt.

Mar 15

The login already has an account under a different user name

This happened to me after moving a database from another instance.

The following link and below SQL helped me resolve it.

ALTER AUTHORIZATION ON DATABASE::MyDatabase to sa;

Make sure you keep the capitalization.

Dec 19

Win7 / 2008 padlock icon on folders

We recently had this, and found by ensuring to add a generic (and relevant) security group to the folder ntfs security fixed two things.  The first is that the application began working, which is always a good thing.  Second, the icon disappeared.

It would be very helpful if MS either provided a hover tip for this icon, or provide a contrite icon definition appendix.  If anyone is deleriously bored enough to try this, please post back.

Dec 19

AppV and UAC

During the sequencing of a relatively old MSAccess application, I initially struggled with the UAC on the application.

I found that during the installation step, UAC was being called.

When I went to run the application as part of the later steps however, the UAC prompt no longer appeared.

I am now in the middle of deploying the stream, and will then find out if this has allowed the UAC to be by-passed.

The application is calling an .exe which then handles calls to an .mdb file and manage file access.  This will also be my first time streaming the pre-required files and dll registrations, but still calling the .exe from over the network/SAN.

In order to bypass the UAC, in the AppV osd file I had to add as this article suggests in step two:

<ENVLIST>
    <ENVIRONMENT VARIABLE=”__COMPAT_LAYER”>RunAsInvoker</ENVIRONMENT>
   </ENVLIST>
  </VIRTUALENV>  (not this last line, that’s just to show the context of where in the osd I added the preceeding lines)

Jul 28

Compare Directories of Files

From time to time, you may find that you need to compare a couple of files.  This is done easily in powershell like so:

Compare-Object -ReferenceObject $(get-content C:\….PathToFile) -DifferenceObject $(get-content C:\…PathToComparisonFile) -IncludeEqual

-IncludeEqual gives a line by line comparison of the file

I was recently faced with receiving an update from a software vendor that was an entire directory.  Rather than wait for them to explain what files they might have changed, I doctored up the below powershell code that will do the job (Disclaimer – Use at your own risk!)

 

#KMT Compare a List of Two Directories for discrepencies in their plain-text content
#July 2011
#http://blog.demo-listen.com
#
# Source Directory
$sourceDir = ‘\\pc123\dir1\someDir’

# Comparison Directory
$CompareDir = ‘\\pc123\dir2\someOtherDir’

#Below you can add in the file extensions you would like to search
$fileExtensionsToSearch = @(‘*.txt’,'*.php’,'*.xml’,'*.js’,'*.htm’,'*.css’,'*.html’,'*.gif’)

# Choose your directory of reference
$source = get-childitem $sourceDir -Include @($fileExtensionsToSearch)`
-recurse -force | foreach-object -process { $_.FullName }

# Choose your directory of new data
$vendor = get-childitem $CompareDir -Include @($fileExtensionsToSearch)`
-recurse -force | foreach-object -process { $_.FullName }
   
    $filecount = 0
    do
    {
    #You can comment out the write-hosts below if you prefer less verbose information during the comparisons
    write-host ‘Comparing file number:’($filecount+1) ‘of’ $vendor.Length
    write-host ‘Comparing file names:’$vendor[$filecount]‘and’ $source[$filecount]
    #write-host $vendor[$filecount]
    Compare-Object -ReferenceObject $(get-content $source[$filecount]) -DifferenceObject $(get-content $vendor[$filecount])
    $filecount++
    }
    while ($filecount -le ($vendor.Length-1))
   
    # If you find a file with differences, you can further look at just two files by putting the paths in below and uncommenting both lines
    # This will give a line by line comparison of both files
    # the extra variable is because the number zero is the first number used, and in the above code
    # that’s reworked in the write-host so it’s more readable to me
    # you can always take this out, just ensure the while less than stays at a length of -1
   
    #$filenumber = 162
    #Compare-Object -ReferenceObject $(get-content $source[($filenumber -1)]) -DifferenceObject $(get-content $vendor[($filenumber -1)]) -IncludeEqual

Jun 29

Batch Image Conversion Tif to JPG PNG

I am working on getting a powershell script that will batch-convert images from one format to another.  Once I have a working script I’ll post that here.

Jun 29

Office Corrupted Templates

An organization recently had an issue whereby their office dot templates would cause MS Office (all versions) to crash if the file was saved in native .dotx format.

Interestingly, when the file was saved in .dotx with compatbility mode, the file would not crash Word.  Normally you’d just fix that one template and be on your way with things, however when you have tens of templates, you want to automate this.

Below is macro code that can batch re-save office files as new files.  Doing this removes any corruption or bad formatting.  If I make time I’ll port this over to PowerShell.

**Disclaimer** Use entirely at your own risk!

 


Sub ResaveTemplates()
Dim sPath As String, sFilename As String, sConvertPath As String, sStarterDoc As String
Dim count As Integer, iPos As Integer
Dim oDoc As Document

Dim fso As FileSystemObject
Dim stream As TextStream
Dim sError As String, sErrorLogName As String, sErrorLogPath As String
Dim i As Integer
Dim sCreateFolder As String, sStarterPath As String, sWorkingPath As String

Set fso = New FileSystemObject

‘logging to C:\ will error
sErrorLogPath = “c:\logs”
If Right(sErrorLogPath, 1) <> “\” Then sErrorLogPath = sErrorLogPath & “\”
sErrorLogName = sErrorLogPath & GetTheTimeStamp() & “_ConvertError.log”

Set stream = fso.CreateTextFile(sErrorLogName, True)

sError = “DATE” & vbTab & “TIME” & vbTab & “FILENAME” & vbTab & “ERROR_NUM” & vbTab & “ERROR_DESC”
stream.WriteLine sError
sError = “”

On Error GoTo ErrorHandle

count = 0

‘*** UPDATE THESE PATHS!!!!
sConvertPath = “c:\files\Toconvert”
sStarterPath = “c:\files\Converted”

If Right(sConvertPath, 1) <> “\” Then sConvertPath = sConvertPath & “\”
If Right(sStarterPath, 1) <> “\” Then sStarterPath = sStarterPath & “\”
‘**** Cycle through folders in array and convert all documents in each
    sPath = sStarterPath
   
    If Right(sPath, 1) <> “\” Then sPath = sPath & “\”
   
            ‘Search for directories within source directory
            sFilename = Dir(sPath, 1)
            Do While sFilename <> “”
                   
                    sFilename = sPath & sFilename
                    Set oDoc = Application.Documents.Open(FileName:=sFilename)
                    sStarterDoc = oDoc.FullName
                    sFilename = sConvertPath & oDoc.Name
        
                    ‘oDoc.Convert change the wdFormatTemplate97 to save to other formats
                    oDoc.SaveAs2 FileName:=sFilename, FileFormat:=wdFormatTemplate97, AddToRecentfiles:=False
             
                    oDoc.Close
                  
             
               
               ‘ Debug.Print sFilename
               
       
NEXTFILE:
                   
NEXTFILENOCLOSE:
                    sFilename = Dir
           
            Loop

GoTo TheEnd

ErrorHandle:
Select Case Err.Number
Case 91
    Resume NEXTFILE

Case 438
    Resume NEXTFILE
   
  
Case Else
    ‘ Need to Write an Error to the Log
    sError = Date & vbTab & Time & vbTab
    sError = sError & sStarterDoc & vbTab & Err.Number & vbTab & Err.Description
    stream.WriteLine sError
    sError = “”
    If Err.Number <> 5825 And Err.Number <> 4198 Then
        oDoc.Close Savechanges:=wdDoNotSaveChanges
    End If
    Set oDoc = Nothing
   
    Resume NEXTFILE
    ‘Err.Raise Err.Number
End Select

       
TheEnd:
stream.Close
Set oDoc = Nothing
Set fso = Nothing

End
End Sub

Function GetTheTimeStamp() As String
Dim sMM As String, sDD As String, sYYYY As String
Dim sHH As String, sMIN As String, sSS As String
sMM = Month(Date)
sDD = Day(Date)
sYYYY = Year(Date)
sHH = Hour(Time)
sMIN = Minute(Time)
sSS = Second(Time)

If Len(sMM) < 2 Then sMM = “0″ & sMM
If Len(sDD) < 2 Then sDD = “0″ & sDD
If Len(sHH) < 2 Then sHH = “0″ & sHH
If Len(sMIN) < 2 Then sMIN = “0″ & sMIN
If Len(sSS) < 2 Then sSS = “0″ & sSS

GetTheTimeStamp = sYYYY & sMM & sDD & “_” & sHH & sMIN & sSS
End Function

Older posts «