Change the 2 variables $theurl ; the website URL, and $storagedir ; the place you want to store them and watch it go. It has some thing built into it that takes care of url variables, direct url, and some url encoding issues. I tried to comment it as much as I could.
Friday, October 16, 2015
Download MP3s with Powershell
Change the 2 variables $theurl ; the website URL, and $storagedir ; the place you want to store them and watch it go. It has some thing built into it that takes care of url variables, direct url, and some url encoding issues. I tried to comment it as much as I could.
Thursday, September 10, 2015
Turn off those Firewalls–Remotely–With PowerShell
Yet again I was given a task at work. This task was to turn off the Firewalls on hundreds of servers. So instead of logging into each one manually and changing the profiles on all the Firewall Profiles; Domain, Private and Public. I decided let us let PowerShell shine again.Now, they didn’t want the Firewall Services stopped, just the Profile states to be off. So after a little research and some help from some co-workers I put this script together.
Let’s talk about something thing through before I go into the script. The easiest way to turn off these Profile states is to run.
netsh advfirewall set allprofiles state off
This of course needs to be run locally on the machine. So I figured why not just use psexec to run the script. So I made a loop for the servers, looped it on the psexec and away it ran.. It ran VERY slowly. I had hundreds of these to run through. This would not work. So I decided to try and use PowerShell Invoke-Command. This required to have a session started using Enter-PSSession. Which of course gave this error.
Enter-PSSession : Connecting to remote server Server01 failed with the following error message : WinRM cannot process the request
Well that’s not going to work because I need to have the WinRM service installed. I don’t have the much time to get approvals to install the WinRM service on all these machines. So I remembered one of my coworkers had run scripts against a remote machine the other week using PowerShell. So I asked for his secret. The secret was Invoke-WmiMethod. Here is the code simply put.
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList (“CMD.EXE /C netsh advfirewall set allprofiles state off”) –ComputerName Server01
This actually runs the script against the server with no Invoke-Command or other service to be installed. So I set off to write the full script and it is FAST. Sooo much faster than I was hoping for.
$command = "netsh advfirewall set allprofiles state off"
$cmd = "CMD.EXE /C " +$command
ForEach ($server in Get-Content "c:\scripts\computers.txt")
{
$theProc = Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ($cmd) -ComputerName $server
If($theProc.ReturnValue -eq "0"){write-host "$server - Completed successfully"}else{write-host "$server - Completed UNsuccessfully"}
}
Now one of the downfalls of this is, you don’t know if the script worked. Of course you can go see on the server if the script did what it was supposed to do, but that is not what I am talking about. Basically you don’t get the output of the cmd. All you get is ReturnValue of 0 if the command went through correctly. Not that your script ran successfully. Just that your little cmd soldier has been sent into the field with the operations it was told to do successfully.
Wednesday, September 2, 2015
PowerShell – Hanging Get-WmiObject
I ran into something that I didn’t know was an issue with Get-WmiObject. I have been using Get-WmiObject for quite sometime so this was a shock to me. I had written a script to grab the description from servers and dump them to a gridview.
I wanted to run this on 1400 servers. Meaning know it was going to take awhile. When I ended up running it, it took too long, actually waaaay to long. The reason? Some of the Get-WmiObject calls were hanging for what ever reason. No problem I thought lets assign the timeout argument to the Get-WmiObject? Where is the timeout argument? ??? After a bit of searching and reading I learned there is no way to set a timeout to the Get-WmiObject commandlet.
After some more reading I learned that the best way to handing this is to setup the Get-WmiObject as a Job. The job can handle the Get-WmiObject process and if it takes longer than you think it should, kill the job and move on.
I don’t have the old way I was running the script but this is the new way.. I tried to comment it as much as I could.
# try this and catch it if it fails
try {
# Set the try to stop if it error out
$ErrorActionPreference = 'Stop'
# start the Job and assign it to a variable..
# -scriptBlock -- assign the -scriptblock argument to show what to run.. this is where the
# get-wmiobject is run. This is encapsualted in {}
# param -- set the param to pass along the server name from the -ArgumentList to the
# Get-WmiObject commandlet
# -ArgumentList pass in the server information.
# | Wait-Job -Timeout 2 - This tells the job to wait for 2 seconds.
$job = start-job -scriptBlock {param ([string]$server) Get-WmiObject -Class Win32_OperatingSystem -ComputerName $server } -ArgumentList $server | Wait-Job -Timeout 2
# This dumps out the job information to a variable to use later
$results = $job | Receive-Job | select Description
# If the Job state is not completed then it was and error, so write out an error for the
# try/catch to catch.
if ($job.state -ne "Completed") {Write-Error "Error"}
# This is the where we put the variables into an array.
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = $results.Description
}
}
catch {
#catch if there is an error and if there is write that there was one in the lsit array..
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = "Error"
}
}
Here is the full script.
#get the list of servers to scan from serverlist.txt
$serverlist = "C:\scripts\computers.txt"
$List = @()
$i = 0
$fileCount = 0
#get the count of servers for updates to the user.
$fileCount = (Get-Content $serverlist | Measure-Object).Count
#Loop the server list.
foreach ($server in Get-Content $serverlist) {
#increment the number of records proccessed
$i++
#Write to the screen whats happening.
Write-Progress -activity "Connecting to server $server" -status "Scanning: $i of $($fileCount)" -percentComplete (($i / $fileCount) * 100)
# try this and catch it if it fails
try {
# Set the try to stop if it error out
$ErrorActionPreference = 'Stop'
# start the Job and assign it to a variable..
# -scriptBlock -- assign the -scriptblock argument to show what to run.. this is where the get-wmiobject is run. This is encapsualted in {}
# param -- set the param to pass along the server name from the -ArgumentList to the Get-WmiObject commandlet
# -ArgumentList pass in the server information.
# | Wait-Job -Timeout 2 - This tells the job to wait for 2 seconds.
$job = start-job -scriptBlock {param ([string]$server) Get-WmiObject -Class Win32_OperatingSystem -ComputerName $server } -ArgumentList $server | Wait-Job -Timeout 2
# This dumps out the job information to a variable to use later
$results = $job | Receive-Job | select Description
# If the Job state is not completed then it was and error, so write out an error for the try/catch to catch.
if ($job.state -ne "Completed") {Write-Error "Error"}
# This is the where we put the variables into an array.
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = $results.Description
}
}
catch {
#catch if there is an error and if there is write that there was one in the lsit array..
$List += [pscustomobject]@{
'ComputerName' = $server
'Description' = "Error"
}
}
}
$List | Out-GridView