
What is a labcast
An online presentation with guided video demonstrations where you also get the chance to perform these same exercises on your own hands-on virtual lab that we provide during the session. As you face challenges in your lab, our instructors virtually take control of your lab to guide you through the tasks, giving you experience-based knowledge on the Microsoft product or topic.
Registration and seating for the upcoming live event is limited. If you are watching the on-demand version, there are no live instructors or registration limitations.
P.S Does anybody know the URL for the first one? Thanks Andy!
The other day I was trying to use the PowerShell Community Extensions (PSCX) Write-Zip cmdlet to archive my local scripts folder, but when I opened the compressed file I could see that all the folders, and subfolders were stored at the root level even though I didn't use the -FlattenPaths parameter. This is the command I used:
PS > dir d:\scripts -rec | Write-Zip -level 9 -IncludeEmptyDirectories -OutputPath D:\Scripts.zip
Why is that? Unfortunately, when binding from input objects, Write-Zip doesn't know how to preserve the paths in a reliable way. Files coming in could be coming from different parts of the filesystem and there is no way to represent all of the source files in a single relative hierarchy (which is how zips store things) because the files might be coming from different drives, from folders inside other folders, etc.
But there is a way around it:
PS > Write-Zip -level 9 -IncludeEmptyDirectories -Path d:\scripts -OutputPath D:\Scripts.zip
That way, Write-Zip knows that the source is from a single hierarchy and it can definitely represent that in the zip. In addition, it will recurse all subfolders too, if you specify a folder to -OutputPath.
I want to thank Oisin, a fellow MVP and one of the master minds behind the PSCX project, for helping me out with it. You should definitely try PSCX if you haven't so far!
List of cmdlets in PSCX v1.1
ConvertFrom-Base64 ConvertTo-Base64
ConvertTo-MacOs9LineEnding ConvertTo-UnixLineEnding
ConvertTo-WindowsLineEnding Convert-Xml
Disconnect-TerminalSession Export-Bitmap
Format-Byte Format-Hex
Format-Xml Get-ADObject
Get-Clipboard Get-DhcpServer
Get-DomainController Get-ExportedType
Get-FileVersionInfo Get-ForegroundWindow
Get-Hash Get-MountPoint
Get-PEHeader Get-Privilege
Get-PSSnapinHelp Get-Random
Get-ReparsePoint Get-ShortPath
Get-TabExpansion Get-TerminalSession
Import-Bitmap Join-String
New-Hardlink New-Junction
New-Shortcut New-Symlink
Out-Clipboard Ping-Host
Remove-MountPoint Remove-ReparsePoint
Resize-Bitmap Resolve-Assembly
Resolve-Host Select-Xml
Send-SmtpMail Set-Clipboard
Set-FileTime Set-ForegroundWindow
Set-Privilege Set-VolumeLabel
Split-String Start-Process
Start-TabExpansion Stop-TerminalSession
Test-Assembly Test-Xml
Write-BZip2 Write-Clipboard
Write-GZip Write-Tar
Looking for an easy way to query DNS servers in PowerShell? Check out Joel's blog, he just made it possible with Get-Dns.
As you already know, all SysInternals utilities are available as a file share. Meaning you can run the tools directly from the Internet (e.g http://blogs.microsoft.co.il/controlpanel/blogs/$live.sysinternals.com\<toolName>), navigate to them with your browser or even map a drive on your local computer.
The SysInternals tools suite is a must have on any sysadmin machine. On my computer I keep them in a special directory (c:\sysint). From time to time the tools get updated or new tools get published and you might not know when it happens.
This is where Get-SysInternals comes into place. It lists the file share and compares each file's last modified date to the corresponding file on the local directory (if exists). If the 'live' file is newer, it is copied to the local directory and a yellow message in echoed to the console, new tools are painted in green. A log file is also generated into the specified directory by the name of changes.log.
At first I thought to compare the utilities file version info, but as you can see from the below, not all files have a version so I used the last modified date (lastWriteTime) instead.
PS > dir \\live.sysinternals.com\Tools -filter *.exe | select -expand vrsionInfo | ft @{l="Name";e={split-path $_.fileName -leaf}},FileVersion -auto
Name FileVersion
---- -----------
accesschk.exe 4.20
AccessEnum.exe 1.32
accvio.EXE
ADExplorer.exe 1.01
ADInsight.exe 1.01
adrestore.exe
Autologon.exe 2.10
autoruns.exe 9.33
autorunsc.exe 9.33
Bginfo.exe 4, 14, 0, 0
Cacheset.exe
Clockres.exe
Contig.exe 1.54
ctrl2cap.exe
Dbgview.exe 4.75
DEFRAG.EXE
Desktops.exe 1.00
diskext.exe 1.1
Diskmnt.exe
Diskmon.exe 2.01
DiskView.exe
du.exe 1.31
efsdump.exe
Filemon.exe 7.04
handle.exe 3.41
...
The default local destination directory for the files is 'c:\sysint' and it will be created automatically if it doesn't exist. If you want another directory of your choice then simply run it like so: 'Get-SysInternals D:\otherDirName'
function Get-SysInternals {
param ( $sysIntDir="c:\sysint" )
if(!(Test-Path -Path $sysIntDir -PathType Container))
{
$null = New-Item -Type Directory -Path $sysIntDir -Force
}
$log = join-path $sysIntDir "changes.log"
Add-Content -force $log -value "`n`n[$(get-date)]SysInternals sync has been started"
dir \\live.sysinternals.com\tools -recurse | foreach {
$fileName = $_.name
$localFile = join-path $sysIntDir $_.name
$exist = test-path $localFile
$msgNew = "new utility found: $fileName , downloading..."
$msgUpdate = "file : $fileName is newer, updating..."
$msgNoChange = "nothing changed for: $fileName"
if($exist){
if($_.lastWriteTime -gt (Get-Item $localFile).lastWriteTime)
{
Copy-Item $_.fullname $sysIntDir -force
Write-Host $msgUpdate -fore yellow
Add-Content -force $log -value $msgUpdate
}
else
{
Add-Content $log -force -value $msgNoChange
Write-Host $msgNoChange
}
}
else
{
if($_.extension -eq ".exe")
{
Write-Host $msgNew -fore green
Add-Content -force $log -value $msgNew
}
Copy-Item $_.fullname $sysIntDir -force
}
}
}
And a sample output
PS > Get-SysInternals
File: accesschk.exe is newer, updating...
File: AccessEnum.exe is newer, updating...
New utility found: accvio.EXE, downloading...
File: AdExplorer.chm is newer, updating...
File: ADExplorer.exe is newer, updating...
File: ADInsight.chm is newer, updating...
File: ADInsight.exe is newer, updating...
File: adrestore.exe is newer, updating...
File: Autologon.exe is newer, updating...
File: autoruns.chm is newer, updating...
File: autoruns.exe is newer, updating...
File: autorunsc.exe is newer, updating...
File: Bginfo.exe is newer, updating...
File: Cacheset.exe is newer, updating...
File: Clockres.exe is newer, updating...
File: Contig.exe is newer, updating...
File: ctrl2cap.amd.sys is newer, updating...
File: ctrl2cap.exe is newer, updating...
File: ctrl2cap.nt4.sys is newer, updating...
File: ctrl2cap.nt5.sys is newer, updating...
File: dbgview.chm is newer, updating...
File: Dbgview.exe is newer, updating...
New utility found: DEFRAG.EXE, downloading...
New utility found: Desktops.exe, downloading...
File: diskext.exe is newer, updating...
File: Diskmnt.exe is newer, updating...
File: Diskmnt.hlp is newer, updating...
File: Diskmon.exe is newer, updating...
...
Now all that is left to do is run it once in a while (I run it on every Sunday) and see if there were any changes to the live share. This is what I use to *schedule* it, put it in your PowerShell profile and wait for next Sunday ;-):
if( (get-date -f dddd) -eq "sunday") { Get-SysInternals }