Posts Tagged ‘powershell’

Changing network configuration can be a real pain if you use your computer, a notebook for example, in more than one different network where you need a static configuration instead of a dynamic. Although Windows offers one alternate configuration it is quite circumstantial to access. The following PowerShell script will change network configurations with only a few clicks. It toggles them between dynamic and static, while it uses either static values you can enter or the ones the DHCP used itself before (default) (if you haven't executed any PowerShell scripts on your computer before, you will need to change your execution policy first - follow this tutorial to do so):

Get-WmiObject win32_networkadapterconfiguration | foreach-object { if($_.dhcpenabled -eq "true") {$akku = $_}}
if ($akku) {
$wmi = Get-WmiObject win32_networkadapterconfiguration | where{$_.ipenabled -eq "true" -and $_.dhcpenabled -eq "true"}
$ip = ($wmi.IPAddress[0])
$gate = $wmi.DefaultIPGateway
$subnet = ($wmi.ipsubnet[0])
$wmi.enablestatic($ip,$subnet)
$wmi.setgateways($gate)
$dns="8.8.8.8","8.8.4.4"
$wmi.setdnsserversearchorder($dns)
}
else {
$wmi = Get-WmiObject win32_networkadapterconfiguration | where {($_.DefaultIPGateway) -and !($_.dhcpenabled)}
$wmi.enabledhcp()
$wmi.setdnsserversearchorder()
}
$akku = ""

This script will use the same values the DHCP used for your static configuration - you will want to set your own IP, Gateway and Subnet though. To do that just replace the bold printed values with the appropriate IPs in double-quotes (e.g. "192.168.1.100").

To actually execute the script, you need to paste it into a notepad document and save it as .ps1 file. It has to be run with administrative rights, so either run it from an elevated powershell or create a link to the file's context menu that runs it in elevated mode.

If you experience issues with the character set, make sure that all double-quotes in the copied text look the same. If not, rewrite the appropriate ones.

Powershell scripts can be run on any Windows system as long as they are run from the ISE by pushing the green play button but as soon as you want to run it from the cmd or the desktop file you'll get hit by an error:

script1.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170

This error happens due to a security measure which won't let scripts be executed on your system without you having approved of it. You can do so by opening up a powershell with administrative rights (search for powershell in the main menu and select Run as administrator from the context menu) and entering:

set-executionpolicy remotesigned

Returnvalue: 2147749891 in wmi EnableStatic method

Wednesday, June 13, 2012 posted by CSch

Successfully using the EnableStatic method for example in powershell always gives the Returnvalue 0. If that is not the case, something will most likely have gone wrong.

If you are returned the value 2147749891, this is a sign for a lack of administrative rights. The action you want to perform with your script most likely goes beyond the rights of a normal user which is why you need to run your script as administrator.

Returnvalue: 2147786788 in wmi EnableStatic method

Tuesday, June 12, 2012 posted by CSch

Successfully using the EnableStatic method for example in powershell always gives the Returnvalue 0. If that is not the case, something will most likely have gone wrong.

If you are returned the value 2147786788, this is a sign for a write lock of some sort, meaning you have to look for running processes that are already using your target object. Most likely you just need to close the network configuration windows if you still have them open.

Using extra modules in Windows PowerShell

Tuesday, March 20, 2012 posted by CSch

Windows PowerShell gives you the option to implement extra modules which can be used from within your scripts after invoking them with the appropriate command. For demonstrative purposes I will use the WASP module (Windows Automation Snapin for PowerShell) here. You can download it from:

http://wasp.codeplex.com/releases/view/22118

After downloading, unpack the file and drag the contained WASP folder over to the PowerShell modules directory (C:\Windows\System32\WindowsPowerShell\v1.0\Modules). To use it in your script, place the invocation before any of the module's commands. The invocation is

Import-Module WASP

Replace WASP with the name of the module you want to use. In the following script you can now use the commands associated with the module, e.g. select-window for the module I used.

Monitor Processes With Windows PowerShell

Tuesday, February 28, 2012 posted by CSch

Maybe you have already come across applications that require you to rearrange things on your desktop for optimal visibility or which you only use in combination with other programs or items - an automated startup or rearrangement would come handy in those situation.

The following little PowerShell script allows just this - automatical actions on process start and/or end.

$target = "firefox"
$process = Get-Process | Where-Object {$_.ProcessName -eq $target}
while ($true)
{
while (!($process))
{
$process = Get-Process | Where-Object {$_.ProcessName -eq $target}
start-sleep -s 5
}
if ($process)
{
"Place action on process start here"
$process.WaitForExit()
start-sleep -s 2
$process = Get-Process | Where-Object {$_.ProcessName -eq $target}
"Place action on process exit here"
}
}

The script above runs continuously until it is terminated or the current session is ended. With a wait time of 5 seconds to give the CPU a break it checks if the process is running - if not, it continues to check, if yes, it spills out some text you can replace with the action to perform on process start and waits until the process is ended. Afterwards, it returns some text to replace and continues to wait for process start again. Currently, the process that is monitored is firefox and is specified in the $target variable at the top of the code.

To run the script, copy and paste it into a notepad, save it as .ps1 file and schedule it on startup with the Windows Scheduled Tasks service if you like. To run the script completely without pop-ups, have a look here.

How to Execute PowerShell Scripts Without Pop-Up Window

Monday, February 27, 2012 posted by CSch

PowerShell scripts are hard to run without any kind of popup. Without a small workaround, it may even be impossible, even if you specify the -WindowStyle Hidden switch - this will only result in the PowerShell window blinking up for a split second and disappearing afterwards.

You can circumvent this issue by launching the PowerShell script from a small VBScript which looks as follows:

command = "powershell.exe -nologo -command C:\Users\howtoforge\Desktop\loop.ps1"
set shell = CreateObject("WScript.Shell")
shell.Run command,0

Save the script as .vbs file. The -command switch is followed by the location of your PowerShell script - give the full path here (my PS script is on C:\Users\howtoforge\Desktop and is called loop.ps1). This VBS frame will cause the PowerShell script to work silently; it will no longer display any cmd window.

Windows Powershell Script to Export and Import Sound Schemes

Monday, February 13, 2012 posted by CSch

Windows 7 offers the possibility to switch between preinstalled sound schemes and also create new ones and delete those again. What it does not provide however is a way to export and import those schemes to use them on other systems. There is a way to do this but it involves copying over all the custom sound files as well as exporting and importing specific registry keys. This might be a bit too complicated for someone who just wants all their Windows systems to play some nice bird chirp at logon.

Luckily, what is possible on Windows is also scriptable in PowerShell. Therefore the following script is able to export custom sound schemes into a zipped package, including all sound files and needed registry items and also import them onto another system. All the audio files used for the custom scheme to export need to be in the C:\Windows\Media directory - on import, they are all unpacked back there and will not be found if the registry points somewhere else.

$x = "nil"

function SelectFileDialog
{
param([string]$Title,[string]$Directory,[string]$Filter="Zip archives (*.zip) |*.zip")
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$bFile = New-Object System.Windows.Forms.OpenFileDialog
$bFile.ShowHelp = $true
$bFile.Title = $Title
$bFile.InitialDirectory = $Directory
$bFile.Filter = $Filter
$Show = $bFile.ShowDialog()
If ($Show -eq "OK")
{
Return $bFile.FileName
}
Else
{
Write-Error "Cancelled by user."
}
}

function NewZip
{
param([string]$zipFilename)
$l = $zipFilename.length-4
$iszip = $zipFilename.substring($l)
if ( $iszip -ne ".zip")
{
$zipFilename = $zipFilename + ".zip"
}
set-content $zipFilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipFilename).IsReadOnly = $false
}

function AddZip
{
param([string]$zipFilename)
$l = $zipFilename.length-4
$iszip = $zipFilename.substring($l)
if ( $iszip -ne ".zip")
{
$zipFilename = $zipFilename + ".zip"
}$l = $zipFilename.length-4
$iszip = $zipFilename.substring($l)
if ( $iszip -ne ".zip")
{
$zipFilename = $zipFilename + ".zip"
}
$shellApplication = new-object -com shell.Application
$zipPackage = $shellApplication.NameSpace($zipFilename)

foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}

function ExtractZip
{
param([string]$zipFilename, [string] $destination)

if(test-path($zipFilename))
{
$shellApplication = new-object -com shell.Application
$zipPackage = $shellApplication.NameSpace($zipFilename)
$destinationFolder = $shellApplication.NameSpace($destination)
$destinationFolder.CopyHere($zipPackage.Items())
}
}

$objshell = New-Object -ComObject Shell.Application
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)

$objform = New-Object System.Windows.Forms.Form
$objform.Text = “Export Windows 7 Sound Scheme”
$objform.Size = New-Object System.Drawing.Size(330,160)
$objform.StartPosition = “CenterScreen”

$objform.KeyPreview = $True
$objform.Add_KeyDown({if ($_.KeyCode -eq “Escape”) {$objform.Close()}})

$exportButton = New-Object System.Windows.Forms.Button
$exportButton.Location = New-Object System.Drawing.Size(20,70)
$exportButton.Size = New-Object System.Drawing.Size(75,23)
$exportButton.Text = “Export”
$exportButton.Add_Click({$x=”exp”;$objform.Close()})
$objform.Controls.Add($exportButton)

$importButton = New-Object System.Windows.Forms.Button
$importButton.Location = New-Object System.Drawing.Size(100,70)
$importButton.Size = New-Object System.Drawing.Size(75,23)
$importButton.Text = “Import”
$importButton.Add_Click({$x=”imp”; $objform.Close()})
$objform.Controls.Add($importButton)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(180,70)
$cancelButton.Size = New-Object System.Drawing.Size(75,23)
$cancelButton.Text = “Cancel”
$cancelButton.Add_Click({$x=”nil”;$objform.Close()})
$objform.Controls.Add($cancelButton)

$objlabel = New-Object System.Windows.Forms.Label
$objlabel.Location = New-Object System.Drawing.Size(10,20)
$objlabel.Size = New-Object System.Drawing.Size(280,40)
$objlabel.Text = “Do you want to export your current theme or import a new theme?”
$objform.Controls.Add($objlabel)

$objform.Add_Shown({$objform.Activate()})
[void] $objform.ShowDialog()

if($x -eq "nil") {exit}

if($x -eq "exp")
{
cd C:\Users\howtoforge\Desktop
$ts = (get-itemproperty (get-item HKCU:\AppEvents\Schemes).PSPath)."(default)"
$a = @()
$b = @()
newzip $ts
Get-ChildItem HKCU:\AppEvents\Schemes\Apps\ | Get-ChildItem | Get-ChildItem |
Foreach-Object {if ((get-itemproperty $_.PSPath)."(default)" -notlike "C:\Windows\Media\*\*"){($efg = ((get-itemproperty $_.PSPath).PSChildName));
if ($efg -eq $ts) { $a += ((get-itemproperty $_.PSPath)."(default)")
}}}
foreach ($i in $a){ if ($i) {$b += get-item $i}}
$b = $b | select -uniq
get-item $b | addzip $ts
reg export HKCU\AppEvents ($ts + ".reg")
get-item ($ts + ".reg") | addzip $ts
remove-item ($ts + ".reg")
}

if($x -eq "imp")
{
$p = SelectFileDialog
if ($p)
{
$ppp = (gci $p | select -expandproperty name)
$ps = $ppp.substring(0,$ppp.length-4)
extractzip $p C:\Windows\Media
regedit ("C:\Windows\Media\" + $ps + ".reg")
Start-sleep -milliseconds 10000
remove-item ("C:\Windows\Media\" + $ps + ".reg")
$p.remove
}
}

In order to be able to run the script, you need to enable running PowerShell scripts on your systems. Therefore, open a PowerShell as administrator and type in:

set-executionpolicy remotesigned

Now you can run selfmade or signed scripts. Copy and paste the script above into a notepad and find the line that was printed bold here - change my username in the path ("howtoforge") to yours. Then save it as .ps1 file.

Afterwards you can run the script by right-clicking it and running it in PowerShell or setting that as the default program to open ps1 scripts with. A prompt will pop up that will ask you if you want to ex- or import. Exporting will automatically export your current sound scheme to a zip file on your desktop (but only with the audio files lying in the said folder - exporting any schemes with files in a subfolder such as the Windows schemes will result in missing paths).

Copy the zipped package to the target system and run the script from there, choosing Import this time. Browse for the package and open it. The script will then put all the audio files to the C:\Windows\Media folder and import the registry file (a few pop ups will come up upon importing stuff into the registry, just accept them and everything should be fine).

If any issues should occur, make sure the zipped package is saved to a folder you have writing-permissions and everything for - if you changed it to something else than your desktop, this may easily happen.
If you are told that the registry file does not exist, this is because you waited too long to accept the import - after ten seconds, the .reg file is deleted to not clutter the Media folder. Just import again to solve it.

Windows Powershell Script to Sort Music From Folder to Library

Thursday, February 2, 2012 posted by CSch

The aim of the following script was to take music from a single folder with unsorted but tagged audio files and sort them into the music library according to artist and album. It often happens that you have audio files in your browser's download folder or your instant messenger's received files folder where they usually don't belong. The script should be able to move them into your music library and put them into correct folders named after the artist and the album they're on.

 

$controlssource = 1
$controlsdest = 1

$objshell = New-Object -ComObject Shell.Application
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$objform = New-Object System.Windows.Forms.Form
$objform.Text = "Move Audio Data"
$objform.Size = New-Object System.Drawing.Size(300,260)
$objform.StartPosition = "CenterScreen"

$objform.KeyPreview = $True
$objform.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objform.Close()}})

$movebutton = New-Object System.Windows.Forms.Button
$movebutton.Location = New-Object System.Drawing.Size(20,170)
$movebutton.Size = New-Object System.Drawing.Size(75,23)
$movebutton.Text = "Move"
$movebutton.Add_Click({$x="move";$objform.Close()})
$objform.Controls.Add($movebutton)

$copybutton = New-Object System.Windows.Forms.Button
$copybutton.Location = New-Object System.Drawing.Size(100,170)
$copybutton.Size = New-Object System.Drawing.Size(75,23)
$copybutton.Text = "Copy"
$copybutton.Add_Click({$x="copy";$objform.Close()})
$objform.Controls.Add($copybutton)

$cancelbutton = New-Object System.Windows.Forms.Button
$cancelbutton.Location = New-Object System.Drawing.Size(180,170)
$cancelbutton.Size = New-Object System.Drawing.Size(75,23)
$cancelbutton.Text = "Cancel"
$cancelbutton.Add_Click({$a=0;$x="nil";$objform.Close()})
$objform.Controls.Add($cancelbutton)

$objlabel = New-Object System.Windows.Forms.Label
$objlabel.Location = New-Object System.Drawing.Size(10,110)
$objlabel.Size = New-Object System.Drawing.Size(280,40)
$objlabel.Text = "Please specify whether you want to copy or to move your files. Moving the files will remove them from their original directory."
$objform.Controls.Add($objlabel)

if ($controlssource -eq 1){
$objlabel2 = New-Object System.Windows.Forms.Label
$objlabel2.Location = New-Object System.Drawing.Size(10,10)
$objlabel2.Size = New-Object System.Drawing.Size(280,15)
$objlabel2.Text = "Path to file origin:"
$objform.Controls.Add($objlabel2)}

if ($controlssource -eq 1){
$objtextbox = New-Object System.Windows.Forms.TextBox
$objtextbox.Location = New-Object System.Drawing.Size(10,25)
$objtextbox.Size = New-Object System.Drawing.Size(230,20)
$objform.Controls.Add($objtextbox)}

if ($controlsdest -eq 1){
$objlabel3 = New-Object System.Windows.Forms.Label
$objlabel3.Location = New-Object System.Drawing.Size(10,50)
$objlabel3.Size = New-Object System.Drawing.Size(280,15)
$objlabel3.Text = "Path to music library:"
$objform.Controls.Add($objlabel3)}

if ($controlsdest -eq 1){
$objtextbox2 = New-Object System.Windows.Forms.TextBox
$objtextbox2.Location = New-Object System.Drawing.Size(10,65)
$objtextbox2.Size = New-Object System.Drawing.Size(230,20)
$objform.Controls.Add($objtextbox2)}

if ($controlssource -eq 1){
$browsebutton1 = New-Object System.Windows.Forms.Button
$browsebutton1.Location = New-Object System.Drawing.Size(250,24)
$browsebutton1.Size = New-Object System.Drawing.Size(26,22)
$browsebutton1.Text = "..."
$browsebutton1.Add_Click({$fold1 = $objshell.BrowseForFolder(0, "Select Folder", 0, "");$objtextbox.Text = $fold1.self.path})
$objform.Controls.Add($browsebutton1)}

if ($controlsdest -eq 1){
$browsebutton2 = New-Object System.Windows.Forms.Button
$browsebutton2.Location = New-Object System.Drawing.Size(250,64)
$browsebutton2.Size = New-Object System.Drawing.Size(26,22)
$browsebutton2.Text = "..."
$browsebutton2.Add_Click({$fold2 = $objshell.BrowseForFolder(0, "Select Folder", 0, "");$objtextbox2.Text = $fold2.self.path})
$objform.Controls.Add($browsebutton2)}

$objform.Controls.Add($copybutton)

#$objform.topmost = $True

$objform.Add_Shown({$objform.Activate()})
[void] $objform.ShowDialog()

$sFolder = $objtextbox.Text
$mFolder = $objtextbox2.Text
#$sFolder = "C:\Users\Public\Music\Sample Music"
#$mFolder = "C:\Users\howtoforge\Music"
$objfolder = $objshell.namespace($sFolder)

if ($X -eq "nil") {exit}

foreach ($strfilename in $objfolder.items())
{
for ($a ; $a -le 266; $a++)
{
if ($objfolder.getDetailsOf($objfolder.items, $a) -eq "Contributing artists")
#if ($objfolder.getDetailsOf($objfolder.items, $a) -eq "Albuminterpret")
{
$artist = $objfolder.getDetailsOf($strfilename, $a)
}
if($objfolder.getDetailsOf($objfolder.items, $a) -eq "Album")
{
$album = $objfolder.getDetailsOf($strfilename, $a)
}
}
if ($artist -and $album)
{
if (!(test-path($mFolder + "\" + $artist + "\" + $album + $strfilename)))
{
new-item($mFolder + "\" + $artist + "\" + $album) -itemtype directory
if($x -eq "copy")
{
copy-item $strfilename.Path ($mFolder + "\" + $artist + "\" + $album)
}
if($x -eq "move")
{
move-item $strfilename.Path ($mFolder + "\" + $artist + "\" + $album)
}
}
}
clear-variable artist
clear-variable album
$a=0
}

The script runs for every audio file in the specified folder that possesses both given details, here they are Contributing artists and Album (you can change it to look for different details but this does not always make sense since the script later creates the folders in the library depending on those data - there are different artist details however which can be chosen from, since not every audio file has all of them (album artist, contributing artists...). To change them, just change the single instance of them in the script. Adjust their names to the display language of your system!).

If the files have both details specified, the script goes to your library and, if not already present, creates a folder with the artist's title, a folder with the album title inside of that, and copies or moves the file to that location.

If you have fixed folders that you don't want to browse anew everytime you run the script, comment out the top two lines and the two bold lines, uncomment the two lines underneath the latter. Change the path given there to the path of your folders. You can also just uncomment one of them, just make sure to comment out the right lines when you uncomment one.

To run the script, copy and paste it into a notepad and save it as .ps1 file (select All Files from the type dropdown menu). Then right-click the file and run it with windows powershell. If it is not working, you might have to change your execution policy if you have not already done so. To accomplish that, search for powershell in the Windows menu search bar and right-click to run it as administrator. Enter

set-executionpolicy remotesigned

and run the script again. The script works finde on my Windows 7 Enterprise 64bit machine with PowerShell 1.0 installed, if some one has improvements to make I'd be glad to read.

Remove Desktop Clutter On Windows 7 With PowerShell

Friday, January 27, 2012 posted by CSch

All of us know the habit of using the desktop as temporary working directory for all kinds of tasks, afterwards leaving most of the files there thinking you might still need them the next day. The day you use them again however never comes and so they remain on your desktop, eventually filling it up to the bottom right corner.
But for lazy people, there are lazy solutions to delay the task of cleaning and tidying up your computer! Just create a folder called Desktop on your Desktop and stuff everything you don't need into it! Here comes a PowerShell script that does this for you (replace the path to the desktop with the one to yours):

cd C:\Users\howtoforge\Desktop
$path = "C:\Users\howtoforge\Desktop"
$index = 0
$run = 1
while ($run -eq 1) {
if (test-path ($path + "\Desktop_" + $index)) {
$index++
}
else {
mkdir ($path + "\Desktop_" + $index)
$run = 0
}
}
gci $path |
? {$_.Name -notlike "Desktop_*" -and $_.Name -notlike "meta.ps1"} |
Foreach-Object { move-item $_ -destination ($path + "\Desktop_" + $index)}

This script creates a numbered "Desktop_x" folder, takes all the stuff from your desktop except system folders such as the recycle bin, shortcuts and the things you exclude in the script and throws them all inside the created folder.
The only thing you might want to adjust are the items the script excludes - these are given in the line

? {$_.Name -notlike "Desktop_*" -and $_.Name -notlike "meta.ps1"} |

Up to now, the script excludes all the items whose names begin with Desktop_, which is because the script is not supposed to crap its own folders, and the "meta.ps1" file, which is the name I saved the script under on my desktop.
Copy the script into a notepad and save it as .ps1 file - if you get an error message about converting to a different character set, cancel the saving. This happens upon copying the script from the website to notepad - to solve the issue, look through the script in your notepad for double-quotes and replace those that look odd with new ones. You should now be able to save the document without problems.
To add more files to exclude, copy and paste the bold part of the line (including the space character in front of it) right after itself and replace the name (which is meta.ps1) with the file you want to exclude (you may use wildcards (*) to select multiple files).
To run the script, right-click it and select Run with PowerShell.