Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Spazz
Nov 17, 2005

Dr. Arbitrary posted:

I think there's a toolmaking in a month of lunches book that might be up your alley.

Yup, just found it. I'm gonna go with that one since anything I can't figure out I have the internet for. I don't need a reference book, I need practical exercises.

Thanks!

Adbot
ADBOT LOVES YOU

Dren
Jan 5, 2001

Pillbug
lol @ powershell docs

http://technet.microsoft.com/en-us/library/ee176910.aspx posted:

You know how it is: as soon as you have everything set up just perfect, you’ll invariably want (or need) to change things. The files you put in the C:\Scripts folder? Turns out they should really be in C:\Test. Or maybe just the .zip files should be in C:\Test. Or maybe - well, you get the idea. Can you use Windows PowerShell to move items from one location or another? Let’s put it this way: if you couldn’t, it would be pretty silly to have a cmdlet named Move-Item.

It's buzzfeed writes technical documentation.

Fruit Smoothies
Mar 28, 2004

The bat with a ZING
I'm using Invoke-Webrequest in a while($true) loop in order to obtain information from a web server. The protocol is that you keep listening until you get information, and then start another request. The problem is, in the middle of this loop - but in the same script, I need to be able to send requests to it. Is this possible with PS?

CLAM DOWN
Feb 13, 2007




Fruit Smoothies posted:

I'm using Invoke-Webrequest in a while($true) loop in order to obtain information from a web server. The protocol is that you keep listening until you get information, and then start another request. The problem is, in the middle of this loop - but in the same script, I need to be able to send requests to it. Is this possible with PS?

Use background jobs!

code:
$job_code_block = {
    while($true) {
        Invoke-Webrequest
        Do-Stuff
    }
}

Start-Job $job_code_block
Do-OtherStuff
That was from memory but I think it's roughly accurate. More here: http://msdn.microsoft.com/en-us/library/windows/desktop/dd878288

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

CLAM DOWN posted:

Use background jobs!

code:
$job_code_block = {
    while($true) {
        Invoke-Webrequest
        Do-Stuff
    }
}

Start-Job $job_code_block
Do-OtherStuff
That was from memory but I think it's roughly accurate. More here: http://msdn.microsoft.com/en-us/library/windows/desktop/dd878288

Thanks, but I need a way of having the output from the background added to the same console as the input. Doesn't look like this is possible, sadly.

12 rats tied together
Sep 7, 2006

Dren posted:

To see the members of the com object. Is there any way I can get more detailed help about that com object and it's members? What about a list of all the com objects that are available?
Your best bet is probably googling the object and pulling up the msdn documentation about it. For example: http://msdn.microsoft.com/en-us/library/windows/desktop/bb774094(v=vs.85).aspx for Shell.Application. If you're looking for better documentation/autocomplete + etc for com objects, you might want to consider shelling out $11,000 for Visual Studio 2013 Ultimate. :)


quote:

Thanks, but I need a way of having the output from the background added to the same console as the input. Doesn't look like this is possible, sadly.
Is there any reason why you can't poll the results and then conditionally send your request in the while loop?
code:
while ($true) {
    
    $results = Invoke-WebRequest -whatever

        if (($results).content -contains "something")) {
            Send-Request -whatever
            }
}
Specifically, what kind of request are you sending, and what kind of information are you looking for? I want to say that it's probably possible, given that you have all/most of the .NET framework at your disposal, but it might involve approaching the problem in a different way.

ZetsurinPower
Dec 14, 2003

I looooove leftovers!
I posted this in the server thread, but figured it would probably be more at home here. Need some ideas...

Environment:
Multiple 2008 R2 and 2012 file servers
User has a mapped "home drive" to a share on their site's server, each share size is limited via quota management.
This "home drive" is synced via offline files.
There is a fun quirk where the sync partnership breaks once a user hits ~100% of their quota...

I want an automated way to identify users that are above 95% of their quota & their share has not been modified in > 2 weeks. This would help identify users whose local files are not being synced to the servers.

Is this possible? I'm powershell illiterate, but seems like something that can be done.

skipdogg
Nov 29, 2004
Resident SRT-4 Expert

I'm sure it can be done in powershell, but have you looked at the File Server Resource Management tool? You can setup quite a few alerts to be emailed in there. I haven't looked recently, but might want to check that out before spending time on making powershell do it.

ZetsurinPower
Dec 14, 2003

I looooove leftovers!
I can set up alerts for users at a certain % of their quota, but I need a way to single out people from that list who have not modified their share in > 2 weeks. I can't find a way to do that with the canned alerts/reports in Server Resource Manager

CLAM DOWN
Feb 13, 2007




Hey guys, I have to transfer a large number (>15,000,000) of small files totaling about 2TB from a 2003 to 2008 R2 server, maintaining folder structure and NTFS ACLs. Should I stick with robocopy, or would Copy-Item suit me fine here?

ConfusedUs
Feb 24, 2004

Bees?
You want fucking bees?
Here you go!
ROLL INITIATIVE!!





Robocopy with its multi threading and retries and so on is pretty drat good for this sort of automation. It's tried and true for me.

Not sure if copy item is as robust. I've always just used robocopy.

evil_bunnY
Apr 2, 2003

Just /MIR it and log to a file.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

CLAM DOWN posted:

Hey guys, I have to transfer a large number (>15,000,000) of small files totaling about 2TB from a 2003 to 2008 R2 server, maintaining folder structure and NTFS ACLs. Should I stick with robocopy, or would Copy-Item suit me fine here?

Not powershell necessarily but doesn't winrar preserve permissions? Sounds like it'd be easier to copy one big file than lots of little ones.

Alfajor
Jun 10, 2005

The delicious snack cake.

Scaramouche posted:

Not powershell necessarily but doesn't winrar preserve permissions? Sounds like it'd be easier to copy one big file than lots of little ones.

The gains in copy/write time probably don't outweigh the time it would take to compress/decompress. I don't know, kinda talking out of my rear end... but something to consider.

RICHUNCLEPENNYBAGS
Dec 21, 2010

Spazz posted:

Any suggestions on a book for someone who has PS experience but wants to round out their knowledge? I've been writing scripts for about 9~ months now, with past Python experience, but I know I'm missing some stuff.

I was looking at Windows PowerShell Cookbook: The Complete Guide to Scripting Microsoft's Command Shell, but I'm open to other suggestions. Work is reimbursing me so cost isn't an issue as long as it isn't ridiculous.

I would just get the Payette book (PowerShell in Action I think).

12 rats tied together
Sep 7, 2006

CLAM DOWN posted:

Hey guys, I have to transfer a large number (>15,000,000) of small files totaling about 2TB from a 2003 to 2008 R2 server, maintaining folder structure and NTFS ACLs. Should I stick with robocopy, or would Copy-Item suit me fine here?

I was involved in a similiar situation where I re-wrote part of our NAnt deployment scripts into Powershell in an attempt to cut down the superfluous copying of around 80,000 files of varying sizes. NAnt was doing it in about 2, maybe 2.5 hours.

The script I wrote generated filehashes and stored them in a file on the destination, pre-deployment. It then did a simple -neq check on each file, running locally at the destination, and copied a file over from staging if the hashes didn't match. I cut the deployment time for 80,000 files + 80,000 changes down to about 20 minutes, which was a pretty huge improvement! Robocopy just copied all 80,000 files over in about 8 minutes, which beat my best-case scenario of "no changes" by about 2 minutes. There was really no point in trying to do a diff and only copying changes if Robocopy could just copy the entire drat thing in less time.

So yeah probably just use robocopy. It might be out of your control but you may also want to reconsider having 2TB of data on a win server machine instead of a SAN or something.

AlternateAccount
Apr 25, 2005
FYGM
So this might not be a specifically Powershell thing, but:

I've created a script that does a bunch of stuff to deprov a user account. Disables it, strips all the groups, moves it to a holding OU for eventual deletion, etc.
When I run it from my desktop machine, it works great. No problems at all.
When I copy the script to the server(2k12r2 DC) and tried to set it up as a scheduled task, it gives all Access Denied errors. Even if I try to run it from a command prompt, same thing, Access Denied errors. Tried running as admin and I've run it as a Domain Admin account.
What's different about these two environments that keeps it from flying?

ConfusedUs
Feb 24, 2004

Bees?
You want fucking bees?
Here you go!
ROLL INITIATIVE!!





AlternateAccount posted:

So this might not be a specifically Powershell thing, but:

I've created a script that does a bunch of stuff to deprov a user account. Disables it, strips all the groups, moves it to a holding OU for eventual deletion, etc.
When I run it from my desktop machine, it works great. No problems at all.
When I copy the script to the server(2k12r2 DC) and tried to set it up as a scheduled task, it gives all Access Denied errors. Even if I try to run it from a command prompt, same thing, Access Denied errors. Tried running as admin and I've run it as a Domain Admin account.
What's different about these two environments that keeps it from flying?

Is this a Set-ExecutionPolicy thing, perhaps?

Get-Help Set-ExecutionPolicy

Basically, by default, powershell won't run scripts that are from another system.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
Couldn't give us a look at that script could you?

AlternateAccount
Apr 25, 2005
FYGM

ConfusedUs posted:

Is this a Set-ExecutionPolicy thing, perhaps?

Get-Help Set-ExecutionPolicy

Basically, by default, powershell won't run scripts that are from another system.

This was it, thanks. Feels like something I should have known, but I didn't! Much, much appreciated. Well that kind of worked, but I am still getting "Access is denied" messages for certain commandlets like Move-ADObject or Get-ADUser that I don't get when running on my local machine.

Swink posted:

Couldn't give us a look at that script could you?

Was this to examine what my issue is or were you wanting to know how I did a particular thing?

AlternateAccount fucked around with this message at 15:27 on Sep 23, 2014

AreWeDrunkYet
Jul 8, 2006

AlternateAccount posted:

This was it, thanks. Feels like something I should have known, but I didn't! Much, much appreciated. Well that kind of worked, but I am still getting "Access is denied" messages for certain commandlets like Move-ADObject or Get-ADUser that I don't get when running on my local machine.

Are you running the same version of Powershell as on the machine where it's working? Are the necessary modules imported?

AlternateAccount
Apr 25, 2005
FYGM

AreWeDrunkYet posted:

Are you running the same version of Powershell as on the machine where it's working? Are the necessary modules imported?

V4 all around. The only used module is ActiveDirectory, which is being imported successfully.

for more info, here's an example of a line that's running that's kicking back an Access Denied on the "Move-ADObject" part:

code:
Get-ADUser $user | Move-ADObject -targetpath "OU=Completed, OU=Deprovisioning, DC=company, DC=local"
Running the exact same line on my desktop(while subbing an actual user in for the variable) works like a champ.

AlternateAccount fucked around with this message at 21:46 on Sep 23, 2014

simcole
Sep 13, 2003
PATHETIC STALKER
Someone please help. I'm mentally blocked right now.

I'm trying to see which "Microsoft Programs" I have installed that match a certain filter and I need their GUID among other things. So far I created a command to get all data matching "Microsoft" and this works perfect:
code:
gp -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where-Object {$_.Publisher -like "Microsoft*"} | select DisplayName,Publisher,DisplayVersion,PSChildName,InstallDate
Now I want to filter that data and exclude certain programs containing words from an exclusion list.

Exclusion.txt contains:
code:
*paint*
*movie*
code:
gp -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where-Object {$_.Publisher -like "Microsoft*"} | where-Object {$_.DisplayName -notcontains $ExclusionList[0]} | select DisplayName,Publisher,DisplayVersion,PSChildName,InstallDate | export-csv -NoTypeInformation data.csv
This also works if I include the [0]. It will not iterate through on its own, nor will it work if I remove the [0].

I need an export.csv that does all the above and I'm completely stumped. I've tried creating foreach loops etc and I can't get anything working. Can someone write me a snippet please?

simcole fucked around with this message at 05:11 on Sep 24, 2014

brosmike
Jun 26, 2009
There's no need to do it all as a one-liner. I'd probably use a Test-Any implementation and do it something like:

code:
$AllPrograms = Get-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
$MicrosoftPrograms = $AllPrograms | Where-Object Publisher -Like 'Microsoft*'
$NonExcludedPrograms = $MicrosoftPrograms | Where-Object {
    $Name = $_.DisplayName
    -not ($ExclusionList | Test-Any { $Name -like $_ })
}
$NonExcludedPrograms | Select-Object DisplayName,Publisher,DisplayVersion,PSChildName,InstallDate | Export-Csv -NoTypeInformation data.csv
You could do it without Test-Any if you wanted:

code:
$NonExcludedPrograms = $MicrosoftPrograms | Where-Object {
    foreach ($Exclusion in $ExclusionList) {
        if ($_.DisplayName -like $Exclusion) {
            return $false
        }
    }
    return $true
}
Personally I find the first one slightly more readable, but they're both fine.

12 rats tied together
Sep 7, 2006

AlternateAccount posted:

Running the exact same line on my desktop(while subbing an actual user in for the variable) works like a champ.

You're logging into the same user on your desktop and on the DC, right? Powershell isn't elevating to admin as DC-MACHINE1\Administrator and then failing because it isn't DOMAIN\YourAccount who is a domain admin? If you're using the same credentials from two different locations there should be no issue. It seems like a problem with the credentials.

That being said we have a scheduled task VM and all of our scheduled tasks run under a separate scheduled tasks account. I've never tried to interact with AD from the DC itself.

simcole posted:

Someone please help. I'm mentally blocked right now.
There's a lot of stuff going on here. Given the requirements, I would probably do something like:

code:
Get-WmiObject -class win32_product | Where-Object { ($_.Vendor -like "*Microsoft*") -and ($_.Name -notlike "*paint*") -and ($_.Name -notlike "*movie*") } | select Name,Vendor,Caption | export-csv .\test.csv
There are a lot of things that could be going wrong with your original example, so I can't really troubleshoot without wanting to kill myself.

You might need a ForEach-Object loop in there somewhere, and you might be running into problems with -contains and -notcontains being too specific and returning the wrong value. It isn't in your code here but I am assuming you are defining $ExclusionList somewhere? I'm a little confused about the "-notcontains $ExclusionList[0]" part, why do you need the [0]?

If you need to exclude more than two or three types of product, I would suggest you format the script something like:

code:
$arrExcludeValues = @(
"value1",
"value2",
"value3",
)

Get-Thing | Where-Object { $_.Property -notlike $arrExcludeValues } | Do-Thing
I've found that generally Powershell will 'play nice' and do the double-iteration heavy lifting for you (that is, compare each element of $arrExcludeValues with each item returned by Get-Thing). It will probably work. This looks like it is kind of what you were trying to do originally. I don't know what was wrong exactly, but you were doing it kind of weird. :)

simcole
Sep 13, 2003
PATHETIC STALKER
[quote="Reiz" post="435330113"]
There's a lot of stuff going on here. Given the requirements, I would probably do something like:

code:
Get-WmiObject -class win32_product | Where-Object { ($_.Vendor -like "*Microsoft*") -and ($_.Name -notlike "*paint*") -and ($_.Name -notlike "*movie*") } | select Name,Vendor,Caption | export-csv .\test.csv
The problem with doing it via Win32_Product is that I hear that it will cause MSIEXEC to verify all installs and would/could cause my computers to freeze. If I run this across my business network to inventory 500+ computers, I could crash virtual servers etc. I need to grab this from the uninstall data which may not be 100% but it will be close.

simcole
Sep 13, 2003
PATHETIC STALKER

brosmike posted:

There's no need to do it all as a one-liner. I'd probably use a Test-Any implementation and do it something like:

code:
$AllPrograms = Get-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
$MicrosoftPrograms = $AllPrograms | Where-Object Publisher -Like 'Microsoft*'
$NonExcludedPrograms = $MicrosoftPrograms | Where-Object {
    $Name = $_.DisplayName
    -not ($ExclusionList | Test-Any { $Name -like $_ })
}
$NonExcludedPrograms | Select-Object DisplayName,Publisher,DisplayVersion,PSChildName,InstallDate | Export-Csv -NoTypeInformation data.csv
You could do it without Test-Any if you wanted:

code:
$NonExcludedPrograms = $MicrosoftPrograms | Where-Object {
    foreach ($Exclusion in $ExclusionList) {
        if ($_.DisplayName -like $Exclusion) {
            return $false
        }
    }
    return $true
}
Personally I find the first one slightly more readable, but they're both fine.

I got it working with your code. I wasn't sure about the ($exclusion in $exclusionList) but it's working. I'm still not sure I quite grasp how that works. Does $exclusion get set to whatever the item is in each line? How is that variable initialized?

I prefer the 2nd method personally. Thank you kind sir.

AlternateAccount
Apr 25, 2005
FYGM

Reiz posted:

You're logging into the same user on your desktop and on the DC, right? Powershell isn't elevating to admin as DC-MACHINE1\Administrator and then failing because it isn't DOMAIN\YourAccount who is a domain admin? If you're using the same credentials from two different locations there should be no issue. It seems like a problem with the credentials.

That being said we have a scheduled task VM and all of our scheduled tasks run under a separate scheduled tasks account. I've never tried to interact with AD from the DC itself.

Well, eventually once I get this working, it will be running under a system account and not mine. I'm logged into the DC as the same account. I've also tried doing it as a "runas:" from a few other accounts, no go. I am completely stuck.

edit edit edit: OK, I was wrong, apparently all of the commands DO work when I start Powershell as Administrator. So that mystery is solved. Sorry, I apparently got turned around on that one.

Now, when I am trying to run the same script as a scheduled task, I'm testing it using the same account I am logged into the box with an "[ ]Run with the highest privileges" is checked, but it's not appearing to do anything. Is there a trick to getting a script to Run As Admin properly in scheduler?

edit edit edit 2: I GOT IT. FINALLY. So when you set up a script in Task Scheduler, you can't just put MYBIGDUMBSCRIPT.PS1 in the box. You have to put POWERSHELL.EXE and then put your script name in the arguments. Always the dumbest poo poo.

Thanks for the help, everyone.

AlternateAccount fucked around with this message at 21:37 on Sep 24, 2014

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

Yeah task scheduler is a big fuckup in all respects really, paths, quotation marks, permissions, all of it. It's amazing how they tried to duplicate the functionality of chron and make it even more obtuse to use.

brosmike
Jun 26, 2009

simcole posted:

I got it working with your code. I wasn't sure about the ($exclusion in $exclusionList) but it's working. I'm still not sure I quite grasp how that works. Does $exclusion get set to whatever the item is in each line? How is that variable initialized?

I prefer the 2nd method personally. Thank you kind sir.

Yes, the

code:
foreach ($thing in $things) { ... }
syntax loops through all the elements of $things, assigning each element in turn to the $thing variable and running the code in the braces against it. See the foreach statement docs if you'd like more examples.

Note that the foreach statement is not the same thing as the ForEach-Object cmdlet, even though they do similar things and even though you can use "foreach" as an alias for ForEach-Object in normal usage.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
Fun time saving techniques: % = Foreach-Object, ? = where-object.


Use them wisely.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
^ I hate seeing those in scripts. I never remember which is which.

The Electronaut
May 10, 2009

Swink posted:

^ I hate seeing those in scripts. I never remember which is which.

I remember the where shortcut by the fact it is asking a question... ?

simcole
Sep 13, 2003
PATHETIC STALKER
Ok, I have a tough last question. I'm retrieving a list of installed software that's made by adobe. I need to see the time it was last run and report it back. If it was never run I need it to say "Never Run". I know how I can do this via gwmi Win32_product but I can't use this method. It will cause the OS to validate every installed product on the machine and bog everything down. I KNOW there is a way to get this from the registry but I don't know where to begin and google isn't being helpful. Can someone point me in the right direction or give me a snippet? Thanks.

Ninja edit: I need it to work on x64 x32 etc. I think there's 3 places to look to include all that.

Edit2: I hate it when I answer my own questions shortly after I ask, but I'm still partially stuck.

Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where -FilterScript {$_.DisplayName -like "*Adobe*"}| Select-Object DisplayName, Publisher

But I still can't find the "last run" property anywhere. I need to know if my designers are using the full suites or if we can save money by only buying certain applications. Also I guess 32bit version is just removing the wow6432node.

simcole fucked around with this message at 17:57 on Oct 10, 2014

RICHUNCLEPENNYBAGS
Dec 21, 2010

ConfusedUs posted:

Is this a Set-ExecutionPolicy thing, perhaps?

Get-Help Set-ExecutionPolicy

Basically, by default, powershell won't run scripts that are from another system.

By default PowerShell won't run any scripts, unless my memory is failing me.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
Does a last run property actually exist?

I've always assumed you need 3rd party software to track that kind of thing.

simcole
Sep 13, 2003
PATHETIC STALKER

Swink posted:

Does a last run property actually exist?

I've always assumed you need 3rd party software to track that kind of thing.

Its included in the Win32_SoftwareFeature set. I'm not sure if that verify's all the installs too... Can anyone comment on that?

http://msdn.microsoft.com/en-us/library/aa394458(v=vs.85).aspx

It also doesn't work on XP or Server2003. Was hoping to use a different method.

simcole fucked around with this message at 03:14 on Oct 12, 2014

WhoNeedsAName
Nov 30, 2013

Malcolm XML posted:

Fun time saving techniques: % = Foreach-Object, ? = where-object.


Use them wisely.

Saves time when writing, makes them a nightmare to debug when you forget which is which. My scripts are full of them :shepicide:

crunk dork
Jan 15, 2006
As a guy that doesn't have any real practical use for Powershell, I've been having a blast tinkering around and trying to figure out how all these different cmdlets work and what they'd be useful for. Anyone aware of any guided exercises for PS like they have for JavaScript on Code Academy? I don't work with computers professionally (yet!) so I'm really just sitting at home on my couch messing around on my laptop and soaking up what I can on my days off.

Adbot
ADBOT LOVES YOU

TheEffect
Aug 12, 2013
Edit- Got it!

TheEffect fucked around with this message at 18:23 on Oct 13, 2014

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply