A N

October 5, 2015

Delay a certain minute (countdown) with Powershell Write-Progress

Filed under: Tips — donrsh @ 12:24 pm
<#	
	.NOTES
	===========================================================================
	 Created on:   	2015-09-09 
	 Created by:   	Arash Nabi
	 Email: 	    arash@nabi.nu 

	===========================================================================
	.DESCRIPTION 
		The function creates a write-progress bar with coundown. Usefull in script
		when you want to paus a certain minut(s)
	.Exampel
		Delay-Time -Min 10
	
#>
function Delay-Time
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		
		[Parameter(Mandatory = $true,
				   ValueFromPipelineByPropertyName = $true,
				   Position = 0)]
		[int]$Min
	)
	$D = get-date
	$x = $min * 60
	$length = $x / 100
	while ($x -gt 0)
	{
		$f = $d.AddMinutes(1)
		$min = [int](([string]($x/60)).split('.')[0])
		$text = " " + $min + " minutes " + ($x % 60) + " seconds left"
		Write-Progress "Please wait until $f" -status $text -perc ($x/$length) -Verbose
		start-sleep -s 1
		$x--
		Write-Progress -Activity Done! -Completed -Verbose
	}
	
}

Restore Microsoft SQL *.bak file with the help of Powershell

Filed under: Tips — donrsh @ 12:17 pm
<#	
	.NOTES
	===========================================================================
	 Created on:   	2015-09-09 
	 Created by:   	Arash Nabi
	 Email: 	    arash@nabi.nu 

	===========================================================================
	.DESCRIPTION for 'Run-DBQuery' function
		The function connects to a Microsoft SQL database and query a TSQL query
	.Exampel
		Run-DBQuery -Database SERVER\SQLEXPRESS -QueryString "SELECT * FROM [table].[dbo].[DatabaseName]"
	===========================================================================
	.DESCRIPTION for 'Restore-DB' function
		The function restore a *.bak file to a Microsoft SQL database.
	.Exampel
		Restore-DB -Database DatabaseName -ServerInstance SERVER\SQLEXPRESS -BackupFile C:\bakfile.bak -ReplaceDatabase
		You have two switches, ReplaceDatabase and Confirm.
#>
function Run-DBQuery
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		[Parameter(Mandatory = $True,
				   HelpMessage = "Please specify the SQL Server instance. Ex Computer\Instance",
				   ValueFromPipeline = $False)]
		[ValidateNotNullorEmpty()]
		$Database,
		[Parameter(Mandatory = $true,
				   ValueFromPipelineByPropertyName = $true,
				   HelpMessage = "Please specify the TSQL query.",
				   Position = 0)]
		[OutputType([System.Data.DataTable])]
		$QueryString
		
		
	)
	
	$ConnectionString = "Data Source=$Database;Integrated Security=True;User ID=;Password="
	
	$command = New-Object System.Data.SqlClient.SqlCommand ($QueryString, $ConnectionString)
	$adapter = New-Object System.Data.SqlClient.SqlDataAdapter ($command)
	
	#Load the Dataset
	$dataset = New-Object System.Data.DataSet
	[void]$adapter.Fill($dataset)
	
	#Return the Dataset
	return @(, $dataset.Tables[0])
}
function Restore-DB
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		[Parameter(Mandatory = $true,
				   ValueFromPipelineByPropertyName = $False,
				   HelpMessage = "Please specify the SQL Server Database Name. Ex MyDB",
				   Position = 0)]
		[ValidateNotNullorEmpty()]
		$Database,
		[Parameter(Mandatory = $True,
				   HelpMessage = "Please specify the SQL Server instance. Ex Computer\Instance",
				   ValueFromPipeline = $False)]
		[ValidateNotNullorEmpty()]
		$ServerInstance,
		[Parameter(Mandatory = $false,
				   HelpMessage = "Please specify the SQL Server instance. Ex Computer\Instance",
				   ValueFromPipeline = $False)]
		[ValidateNotNullorEmpty()]
		$BackupFile,
		[Parameter(Mandatory = $false,
				   HelpMessage = "Do you want to replace this database?",
				   ValueFromPipeline = $False)]
		[switch]$ReplaceDatabase,
		[Parameter(Mandatory = $false,
				   HelpMessage = "Confrim the action?",
				   ValueFromPipeline = $False)]
		[switch]$Confirm
	)
	try
	{
		$Mod = Get-Module -ListAvailable | Where-Object { $_.Name -eq 'SQLPS' }
		if ($Mod)
		{
			Write-Verbose "Powershell SQL Module exist in $env:COMPUTERNAME. Continuing to restore database $Database"
			Import-Module -Name SQLPS -Verbose -ErrorAction Stop
			$GetDBSettings = Run-DBQuery -Database $ServerInstance -QueryString "select 
    InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
    InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')"
			$SQLDataPath = $GetDBSettings.InstanceDefaultDataPath
			$SQLLogPath = $GetDBSettings.InstanceDefaultLogPath
			
			Write-Verbose "Default Data Path is: $SQLDataPath"
			Write-Verbose "Default Log Path is: $SQLLogPath"
			
			$RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile($Database, "$($SQLDataPath)$Database.mdf")
			$RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("$($Database)_log", "$($SQLLogPath + $Database)_log.ldf")
			
			$params = @{
				'Serverinstance' = $ServerInstance
				'Database' = $Database
				'Backupfile' = $BackupFile
				'RelocateFile' = @($RelocateData, $RelocateLog)
			}
			
			
			if ($DatabaseObject)
			{
				$params.Add('DatabaseObject', $true)
			}
			if ($PSBoundParameters['Verbose'])
			{
				$params.Add('verbose', $true)
			}
			
			if ($ReplaceDatabase)
			{
				$params.Add('ReplaceDatabase', $true)
			}
			if ($Confirm)
			{
				$params.Add('Confirm', $true)
			}
					
			Restore-SqlDatabase @params
		}
		else
		{
			Write-warning "There is no powershell module for SQL exist in $env:COMPUTERNAME. Aborting..." -ForegroundColor Magenta
			return
		}
		
	}
	catch [System.Net.WebException], [System.Exception]
	{
		$errorMessage = $_.Exception.Message
		Write-Warning -Message "$errorMessage"
	}
	finally
	{
		
	}
	
}

Powershell ‘Write-Log’ function

Filed under: Tips — donrsh @ 11:41 am

Powershell function to write log.

<#	
	.NOTES
	===========================================================================
	 Created on:   	2015-10-05 
	 Created by:   	Arash Nabi
	 Email: 	arash@nabi.nu 
	===========================================================================
	.DESCRIPTION
		Write-Log function creates a log file in the $PSScrtipRoot. It's usefull
                to call it in your script and output some message or verbose output. 
	==========================================================================
	.EX
		Write-Log -Message "Email report send"
#> 
function Write-Log
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		[Parameter(Mandatory = $true,
				   ValueFromPipelineByPropertyName = $False,
				   HelpMessage = "Please enter Message for the log",
				   Position = 0,
				   ValueFromPipeline = $True)]
		[ValidateNotNullorEmpty()]
		$Message
		
		
	)
	try
	{
		$LogFolder = "$PSScriptRoot\log"
		$d = get-date
		$M = $d.Month.ToString()
		$Y = $d.Year.ToString()
		$LogFile = "$LogFolder\$("Script" + "-" + $Y + "-" + $M + ".log")"
		if (!(Test-Path -Path $LogFile))
		{
			$Dir = New-Item -Path $LogFolder -ItemType Directory -Force
			$Log = New-Item -Path "$Dir\$("Script" + "-" + $Y + "-" + $M + ".log")" -ItemTyp File -Force
			
		}
		$DateTime = (get-date -Format "yyyy-MM-dd HH:mm:ss")
		if ($PSBoundParameters['Message'])
		{
			"[$DateTime] " + $Message | out-file $LogFile -ErrorAction SilentlyContinue -append
		}
		
	}
	catch [System.Net.WebException], [System.Exception]
	{
		$errorMessage = $_.Exception.Message
		Write-Warning -Message $errorMessage
	}
	finally
	{
	}
}

September 21, 2015

Get Dilbert Cartoon with Powershell

Filed under: Tips — donrsh @ 8:17 am

Get Today’s or even yesterdays Dilbert Cartoon with Powershell with Invoke-WebRequest from http://www.dilbert.com and send it as email with embedded picture.

   <#
   .NOTES 
   ===========================================================================

      Created on:   	2015-09-21 09:05
      Created by:   	Arash Nabi
      Email:            arash@nabi.nu

  ===========================================================================

   .Synopsis
      Send Daily Dilbert Cartoon from www.dilbert.com
   .EXAMPLE
      Todays Dilbert: Get-Dilbert
   .EXAMPLE
      Yestardays Dilbert: Get-Dilbert -last -1
   #>
function Get-Dilbert
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		[Parameter(ValueFromPipelineByPropertyName = $true,
				   HelpMessage = "Choose last date",
				   Position = 0)]
		[ValidateSet ('-1',
		'-2',
		'-3',
		'-4')]
		[int]$Last
		
		
	)
	
	
	Process
	{
		$VerbosePreference = "Continue"
		if ($Last)
		{
			$lastDate = (get-date).AddDays($Last) | get-date -Format "yyyy-MM-dd"
			Write-Verbose 'Invoking website'
			$dil = Invoke-WebRequest -Uri "http://dilbert.com/strip/$LastDate" -UseBasicParsing
			$bild = $dil.Images | Where-Object { $_.class -eq 'img-responsive img-comic' } | Select-Object src
			Invoke-WebRequest $bild.src -OutFile "$PSScriptRoot\$LastDate.gif"
			Write-Verbose 'Sending email'
			Send-MailMessage -to Email.To@domain.com -From Email.From@domain.com -SmtpServer smtp.domain.com -Subject "Dilbert $LastDate" -BodyAsHtml "<br/><img src='$LastDate.gif' />" -Attachments "$PSScriptRoot\$LastDate.gif"
		}
		else
		{
			$today = (get-date -Format "yyyy-MM-dd")
			Write-Verbose 'Invoking website'
			$dil = Invoke-WebRequest -Uri "http://dilbert.com/strip/$today" -UseBasicParsing
			$bild = $dil.Images | Where-Object { $_.class -eq 'img-responsive img-comic' } | Select-Object src
			Invoke-WebRequest $bild.src -OutFile "$PSScriptRoot\$today.gif"
			Write-Verbose 'Sending email'
			Send-MailMessage -to Email.To@domain.com -From Email.From@domain.com -SmtpServer smtp.domain.com -Subject "Dilbert $today" -BodyAsHtml "<br/><img src='$today.gif' />" -Attachments "$PSScriptRoot\$today.gif"
			
		}
		
		
	}
	
}

June 25, 2015

SQL – First and Last day of previous month

Filed under: Tips — donrsh @ 1:36 pm
	select (dateadd(month,datediff(month,(0),getdate())-1,(0))),
	'first day of previous month'
	union
	select (dateadd(month,datediff(month,(0),getdate())-1,(30))),
	'Last day of previous month' 

June 17, 2015

unZip with Powershell

Filed under: Tips — donrsh @ 1:37 pm

Server 2012 comes with Dot.NET 4.5 which has System.IO.Compression.ZipFile which has a ExtractToDirectory method. You should be able to use this from PowerShell.

Here is an example.

First you need to load the assembly ZipFile is in:

[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
Then extract the contents
[System.IO.Compression.ZipFile]::ExtractToDirectory($pathToZip, $targetDir)

If you have updated to PowerShell 5 (Windows Management Framework 5.0) you finally have native cmdlets:

Expand-Archive $pathToZip $targetDir

May 7, 2015

Powershell – [IO.Directory]::EnumerateFiles VS Get-Childitem VS [IO.Directory]::GetFiles

Filed under: Tips — donrsh @ 8:47 am

The goal is to see how long it takes to change file extension of large amount of files using different methods in Powershell.

1) Create 500 000 files
2) Change file extension using [IO.Directory]::EnumerateFiles / Get-Childitem / [IO.Directory]::GetFiles and compare how long it takes.

Create files

1..500000 | % {New-Item -Path C:\utdelat\Archive2 -name "$_.txt" -Value (get-date).ToString() -ItemType file -Force}

Lets change file extension using powershell

############## EnumerateFiles
$newExtensionLOG = "logx"
$EenumerateFiles = Measure-Command -Expression {       
        foreach ($itemEn in [IO.Directory]::EnumerateFiles("C:\utdelat\Archive2"))
        {
           Rename-Item $itemEn -NewName ([System.IO.Path]::ChangeExtension($itemEN,$newExtensionLog)) 
             
        }
} 

 
 $EenumerateFiles
############## Get-ChildItem

$GetChilditem = Measure-Command -Expression {
        $newExtensionXLS = "xls"
        foreach ($itemGet in Get-ChildItem -Path "C:\utdelat\Archive2")
        {
            
           Rename-Item $itemget.FullName -NewName ([System.IO.Path]::ChangeExtension($itemGet,$newExtensionXLS)) 
             
        }
}

$GetChilditem

############## GetFiles

$GetFiles =  Measure-Command -Expression {
        $newExtensionZIP = "zip"
        foreach ($itemZIP in [IO.Directory]::GetFiles("C:\utdelat\Archive2"))
        {
           
            Rename-Item $itemZip -NewName ([System.IO.Path]::ChangeExtension($itemZip,$newExtensionZIP) )
        }
}

$GetFiles

The result is:

[IO.Directory]::EnumerateFiles

Days              : 0
Hours             : 0
Minutes           : 12
Seconds           : 37
Milliseconds      : 312
Ticks             : 7573125757
TotalDays         : 0,00876519184837963
TotalHours        : 0,210364604361111
TotalMinutes      : 12,6218762616667
TotalSeconds      : 757,3125757
TotalMilliseconds : 757312,5757

Get-Childitem

Days              : 0
Hours             : 0
Minutes           : 27
Seconds           : 3
Milliseconds      : 635
Ticks             : 16236359088
TotalDays         : 0,0187920822777778
TotalHours        : 0,451009974666667
TotalMinutes      : 27,06059848
TotalSeconds      : 1623,6359088
TotalMilliseconds : 1623635,9088
[IO.Directory]::GetFiles

Days              : 0
Hours             : 0
Minutes           : 28
Seconds           : 33
Milliseconds      : 451
Ticks             : 17134517876
TotalDays         : 0,019831617912037
TotalHours        : 0,475958829888889
TotalMinutes      : 28,5575297933333
TotalSeconds      : 1713,4517876
TotalMilliseconds : 1713451,7876

February 16, 2015

Compare two dates with powershell

Filed under: Tips — donrsh @ 9:58 am
$StartDate="2014-12-05"

$EndDate=[datetime]”2015-02-12”

NEW-TIMESPAN –Start $StartDate –End $EndDate

November 24, 2014

Copy-Item, Compare-Item, Move-Item

Filed under: Tips — donrsh @ 11:38 am
<#	
	.NOTES
	===========================================================================
	 Created with: 	Powershell ISE Version 4.0
	 Created on:   	2014-11-24 
	 Created by:   	Me
	 Organization: 	Me
	 Filename:     	MoveFiles.ps1
	===========================================================================
	.DESCRIPTION
		The script copies files from source to a temporary folder. It then compare the files and if the 
		result is OK, it will move the files from temporary folder to destination.
#>
$ErrorActionPreference = "stop"

$Source = "C:\utdelat\2\Archived\*"
$Destination = "C:\utdelat\SlutDestination"
$days = "-63" #Everything before this day
$FileName = (Get-Date).tostring(“yyyy-MM-dd-HH-mm-ss”)
$TempFolderDir = "C:\utdelat\Mellan"
 

try
{
	
	
	$TotalSource = Get-ChildItem -Path $Source | Measure-Object
	Write-Host "There is $($TotalSource.count) objects in $Source" -ForegroundColor Green
	Write-Host "Getting list of the files before $days days..." -ForegroundColor Green
	$LastTotal = Get-Childitem -Path $Source | where-object { $_.LastWriteTime -lt (get-date).AddDays($days).date } 
	Write-host "$($LastTotal.count) objects will move from $source" -ForegroundColor Green
	
        if (get-childitem -Path $Source | where-object { $_.LastWriteTime -lt (get-date).AddDays($days).Date })
	    {
			
		$TempFolder = New-Item -itemType Directory -Path $TempFolderDir -Name ($FileName + “---Archive”) -Verbose
		Write-Host "Copying the files to temporary folder $TempFolder" -ForegroundColor Green
		copy-item -Path (Get-Childitem -Path $Source | where-object { $_.LastWriteTime -lt (get-date).AddDays($days).Date }) -destination $TempFolder -force -Verbose
		Write-host "Comparing files in $source with $TempFolder" -ForegroundColor Green
		$diff = Compare-Object -ReferenceObject (dir $source -Recurse | Where-Object { !$_.psiscontainer -and $_.LastWriteTime -lt (get-date).AddDays($days).Date }) -DifferenceObject (dir $TempFolder -Recurse) -property name | Where-Object { $_.sideindicator -eq "<=" }
		
		    if ($diff -eq $null)
		    {			
    		    Write-host "The result is TRUE. Continuing to Move items to $destination" -ForegroundColor Green
			    Move-Item -Path "$TempFolder\*" -destination $Destination -force -Verbose
			}
		        else
		        {
			        Write-Host "Something went wrong. No file copyied to $TempFolder Probably The files are not in sync. " -ForegroundColor Red
		        }

		

	    }
	    else
	    {
		    Write-Host "There is no files less than: $days" -ForegroundColor Red
                    Return
		}
    
	$diff2 = Compare-Object -ReferenceObject (Get-ChildItem $source -Recurse | Where-Object { !$_.psiscontainer -and $_.LastWriteTime -lt (get-date).AddDays($days).Date }) -DifferenceObject (Get-ChildItem $Destination\* -Recurse) -property name | Where-Object { $_.sideindicator -eq "=>" }
                    
             if ($diff2 -eq $null)
             {                      
                 Write-host "The result is TRUE. Continuing to REMOVE items FROM $source with $days days" -ForegroundColor Green
                 Remove-Item  -Path (Get-Childitem -Path $Source | where-object { $_.LastWriteTime -lt (get-date).AddDays($days).Date }) -Verbose -Force
             }
                 else
                  {
                     Write-Host "Something went wrong. No file removed from $Source with $days days. The files are not in sync. " -ForegroundColor Red
                  }
}
catch
{
	
	Write-Host "An error has occurred...  Error details: $_." -ForegroundColor Red
	
	
}

finally
{
	#$TotalDestination = (Get-ChildItem -Path $Destination | where-object { $_.LastWriteTime -lt (get-date).AddDays($days) }) | Measure-Object
	#Write-Host "There is $($TotalDestination.count) objects in $Destination with $days days" -ForegroundColor Green
	Write-Host "End" -ForegroundColor Green
	
}


November 20, 2014

Move files with Powershell (Try – Catch – Finally)

Filed under: Tips — donrsh @ 4:48 pm
$ErrorActionPreference = "stop"
$Source = "c:\share\*"
$Destination = "C:\Test"
$days = "-1"
try
{
    #$problem = $false
    Write-Host "Getting list of the files from last $days days..." -ForegroundColor Green
    $Total = Get-ChildItem -Path $Source | Measure-Object
    Write-Host "There is $($Total.count) objects in $Source" -ForegroundColor Green
    if (get-childitem -Path $Source |  where-object {$_.LastWriteTime -lt (get-date).AddDays($days)})
    {
        
        Write-Host "Moving the files to $destination" -ForegroundColor Green
        move-item -Path $Source -destination $Destination -Verbose
    }
    else
    {
       Write-Host "There is no files less than: $days" -ForegroundColor Red
        
    }

}
catch 
{
    #$problem = $true
    Write-Host "An error has occurred...  Error details: $_." -ForegroundColor Red
    
    
}

finally
{
    
        Write-Host "End" -ForegroundColor Green
        
}
« Newer PostsOlder Posts »

Blog at WordPress.com.