|
Oh, I'm dumb. Scriptblocks don't need to be in quotes. Jobs are workable for me now. I had the entire function in quotes, using backticks at the end of every line.
Raere fucked around with this message at 00:59 on Sep 19, 2015 |
# ? Sep 19, 2015 00:52 |
|
|
# ? May 15, 2024 02:48 |
|
Running into a weird issue - PowerShell remoting isn't enabled in our environment, so I have to use WMI jobs to query computers in parallel. ($job = Get-WMIObject -Class [not important for this example] -ComputerName $computername-AsJob) This works fine if I run the command interactively as myself or as the account I want to use to eventually run the same queries. I have a scheduled job using this command that runs on my workstation under my account while I am logged in (created using Register-ScheduledJob), and that works fine as well. However, creating the task in Task Scheduler on one of our servers, with the account set to the account I want to run the task (and that it should run whether the user is logged on or not) fails. Other Task Scheduler jobs that do not use WMI jobs complete successfully. Going by the $Error variable, the fault is apparently an invalid parameter somewhere in this line and a similar one that calls Receive-Job instead of Wait-Job: foreach ($computer in $computername) { $test = $job | Get-Job -IncludeChildJob | Where Location -eq $computer | Wait-Job -Timeout $timeout ... } The ideal workaround would be to get PowerShell remoting enabled, but I don't think that's happening here. But I'm kind of stumped about what parameter it's actually seeing as invalid, or of any workaround other than removing the job and just letting WMI query in serial - which would likely work, it'd just take forever.
|
# ? Sep 19, 2015 15:07 |
|
Venusy posted:Running into a weird issue - PowerShell remoting isn't enabled in our environment, so I have to use WMI jobs to query computers in parallel. ($job = Get-WMIObject -Class [not important for this example] -ComputerName $computername-AsJob) I'm not sure why it's not working, but you could use runspaces instead of jobs for parallelism. There's a module that handles all the runspace stuff: https://github.com/proxb/PoshRSJob
|
# ? Sep 19, 2015 17:51 |
|
tl;dr I'm an idiot don't mind me OK I just have no idea what's going on, but every time I print anything, "Can't find file " gets put at the beggining. code:
E: AAAAUGH this has infected my entire environment! If I log out and log in, open a powershell window, and just write print "hello" in the window I get back "Can't find file hello" E2: Why am I using print? Did I fall on my head and think I was writing Python? I guess I'm an idiot and I keep calling the "print" command. FISHMANPET fucked around with this message at 22:07 on Sep 21, 2015 |
# ? Sep 21, 2015 21:41 |
|
DUDE NO. What did you make me do to my machine?
|
# ? Sep 21, 2015 22:09 |
|
That's kind of impressive, but also shouldn't have worked as written because I was only "printing" the word match.
|
# ? Sep 21, 2015 22:53 |
|
FISHMANPET posted:That's kind of impressive, but also shouldn't have worked as written because I was only "printing" the word match. I uncommented the first print.
|
# ? Sep 21, 2015 23:03 |
|
Welp, just printing out every file in your Temp dir, nbd.
|
# ? Sep 21, 2015 23:13 |
|
What's the best way to set JPG metadata using Powershell? I have a bunch of JPGs with blank titles and subjects. Said titles and subjects are available in a CSV file, I've written a script that retrieves them and attempts to inject them into the JPG properties but it doesn't work:code:
|
# ? Sep 26, 2015 17:14 |
|
Mr Crucial posted:What's the best way to set JPG metadata using Powershell? I have a bunch of JPGs with blank titles and subjects. Said titles and subjects are available in a CSV file, I've written a script that retrieves them and attempts to inject them into the JPG properties but it doesn't work: You can hook into the COM object that the File Explorer uses to query file metadata. http://blogs.technet.com/b/heyscriptingguy/archive/2014/02/06/use-powershell-to-find-metadata-from-photograph-files.aspx https://social.technet.microsoft.com/Forums/scriptcenter/en-US/8b398413-0728-4a8a-a593-d2e8b92b88f2/editing-image-exif-tags?forum=ITCG
|
# ? Sep 26, 2015 17:27 |
|
Ithaqua posted:You can hook into the COM object that the File Explorer uses to query file metadata. Doesn't work, unfortunately - it's okay for reading certain fields but not for writing anything that was useful to me. In the end I installed ExifTool from here http://www.sno.phy.queensu.ca/~phil/exiftool/ and got Powershell to execute commands against it. Worked perfectly.
|
# ? Sep 28, 2015 09:16 |
I'm scratching my head right now with the way this script behaves. I have a CSV with one column. I'm using Write-Host to see what it's getting read as the output is @{Columnname= List Element}. What am I doing wrong?
|
|
# ? Sep 29, 2015 19:01 |
|
skooma512 posted:I'm scratching my head right now with the way this script behaves.
|
# ? Sep 29, 2015 19:30 |
|
skooma512 posted:I'm scratching my head right now with the way this script behaves. using select-object ?
|
# ? Sep 30, 2015 01:11 |
|
I've got a script based on a dos command. Yeah, I know. REG QUERY $registrystring Is there an easy way to redirect the streams to two separate variables, like stderr to $err and stdout to $out
|
# ? Sep 30, 2015 01:35 |
|
skooma512 posted:I'm scratching my head right now with the way this script behaves. You have to like, do something with the CSV to be able to write-host it. Unless you actually have a big rear end string (like, if you pasted it and then put quotes around it), in which case you don't actually have a CSV you just have a big rear end string. If you have a CSV in a file, and you do something like: "$csv_object = Import-Csv .\csv-in-file.txt"... You now have some amalgamation of a custom object that more or less represents your csv stored inside $csv_object. $csv_object.column1 will show you everything in the first column, where "column1" is the actual name of your column, so $csv_object.date, .time, etc. This output is some form of an array or list or whatever and can be sliced, selected from, and all the other things you learned about in powershell in a month of lunches but didn't have anything to do with and probably forgot about. So, if you want the value of the fourth row in the first column of your csv object you can just do "$csv_object.column1[3]". But, generically, if you actually have a CSV object it should be really hard to do anything with it that isn't immediately useful or obvious. Like, if you pipe it into get-member it's gonna have like 4 methods and then a bunch of properties that correspond to your stuff. quote:Is there an easy way to redirect the streams to two separate variables, like stderr to $err and stdout to $out 12 rats tied together fucked around with this message at 03:19 on Sep 30, 2015 |
# ? Sep 30, 2015 02:53 |
|
Reiz posted:You're probably looking for something like Tee-Object. You're going to want some way to determine between stdout and stderr if you don't already have that. If it were me, I would probably want to move away from using "REG QUERY" and just query the registry directly with powershell since there is a provider for it (run get-psprovider) and you can interact with it more or less like it is a filesystem. Probably. I'm mostly interested because there's a few other legacy systems that I'm in the middle of uplifting to 2008 or 2012 and the good Powershell commands don't always work.
|
# ? Sep 30, 2015 04:11 |
I actually figured it out! Though I did it that same way before, it works now.Briantist posted:Post your code. Import-CSV Book1.csv | Foreach-Object { $computername = $_.computername Remove-Item -path \\$computername\c$\Test Folder } If I simply put $_, it would spit out what I posted originally. Specifying the column name fixed that, though I know I did that before, but it didn't work. That's also the only column in that CSV. Thanks all!
|
|
# ? Sep 30, 2015 04:49 |
|
For what it's worth, if you need to do that in the future it's technically a one liner. To start, a csv with one column is just a list, so you can easily get-content instead of import-csv. But, if for some reason you need to interact with it as a csv (maybe it is generated during some automated process) you can do this:code:
I imagine both of these methods are interpreted into roughly the same operations but in my opinion there's really no need to spend 8 lines doing something that can be appropriately expressed in 1. 12 rats tied together fucked around with this message at 13:39 on Sep 30, 2015 |
# ? Sep 30, 2015 05:56 |
|
Reiz posted:You're probably looking for something like Tee-Object. You're going to want some way to determine between stdout and stderr if you don't already have that. If it were me, I would probably want to move away from using "REG QUERY" and just query the registry directly with powershell since there is a provider for it (run get-psprovider) and you can interact with it more or less like it is a filesystem. I took a look at this today, I agree with you when it comes to a local computer, it's super easy to navigate the registry as a file system. I'm running into issues because I need to check the registry on several thousand servers for the presence of a specific key. I've had mixed results with Invoke-Command, it might be because the target systems are a mix of operating systems. If this is really the way to go then I guess that's ok. What I've been trying to do is create output like: SERVERNAME,Present?,Failurereason The third column is what's giving me a hard time. I want to be able to differentiate between Key not found, Access denied, and network error. I'll probably be dicking around with this off and on all day but if someone knows an easy way to do it, I'm all ears.
|
# ? Sep 30, 2015 18:50 |
|
I would start with a an code:
Hadlock fucked around with this message at 19:25 on Sep 30, 2015 |
# ? Sep 30, 2015 19:18 |
|
I had to solve a similair problem, mine was changing the password on 1000 servers running everywhere from Server 2003 up to 2012 R2. I was also interested in catching the various failure states.code:
Basically: I created $RemoteChangeScript, which is the script I would execute on the remote machine. Then I used a for each loop to go through each computer and try and use invoke-command on that computer. If it failed and went to my catch block, I created a new object that had the computer name (twice, because I got the name 2 ways) and the name of the account I was trying to change, as well as the specific error message, and then returned that. In the RemoteChangeScript if my command to change the password succeeded, I returned a similar object with an "error" message of "success. And if the script failed on the remote computer, I had a catch block that would return an object with that error. So no matter what, my script would return an object with the computer name, the account I was changing, the computer name again, and what the outcome of the command was. This let me separate the successes from the computers I couldn't connect to from the computers that for whatever reason couldn't execute the command locally.
|
# ? Sep 30, 2015 21:41 |
|
Dr. Arbitrary posted:
Doing it on thousands of servers is gonna be tricky, yeah. I've done it on ~200 servers just fine with invoke-command though. I imagine an issue you'll run into will be any minor inefficiencies ballooning up into a serious problem. You might want to look into foreach -parallel. Have a function that takes a computername and runs some tests, start at the first thing that could fail (network) and, on a failure, out-file -append your log message, you can try to script pssessions for the remote reg key check or just cobble together a working invoke. If you foreach -parallel that function call with a list of computers you should be alright, maybe. You can do it one at a time but with 1000+ computers it's gonna be a while. Two other things you might wanna check out are the Microsoft.Win32.Registry class (I'm pretty sure this has a method for remote key query) and, if you have to manage thousands of machines, ansible. You will need some kind of Linux machine for ansible, however.
|
# ? Oct 1, 2015 14:22 |
|
Powershell remoting question: I want to run some commands from client A on server B. The two are in different domains so I am passing an IP address and credential parameter to Invoke-Command to force NTLM auth. Everything's gravy as long the account I am using is an administrator on B. But I also want non-admin accounts to be able to run these commands, so I created and registered a new PSSessionConfiguration and gave FullControl to a non-admin account as described here. However, I am still getting access denied when I try to use the new session configuration. The new configuration works if I connect with my admin account. The specific error is: Access is denied + CategoryInfo : OpenError: (w.x.y.z:String) [], RemoteException + FullyQualifiedErrorId : PSSessionStateBroken Anyone know if there are any other permissions I have to grant to non-admin account? Or how to crack open the error for something a little more specific? Edit: My command: code:
Eggnogium fucked around with this message at 23:15 on Oct 1, 2015 |
# ? Oct 1, 2015 23:12 |
|
Eggnogium posted:Powershell remoting question:
|
# ? Oct 2, 2015 02:15 |
|
Briantist posted:I actually just did this today, giving non-admins access to a new PSSessionConfiguration. I didn't have any problem with it, though I wasn't going between domains. I don't see any issue with the client call. When you set the permissions did you use the UI or did you try to write the SDDL yourself? SDDL is gibberish to me so I used -ShowSecurityDescriptorUI. None of the guides I've found said which permissions were required so I granted Full Control. Interestingly, if I enter the non-admin credentials when trying to connect with the default configuration (for which I haven't changed permissions), I get a slightly different format for the error message: [w.x.y.z] Connecting to remote server w.x.y.z failed with the following error message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic. + CategoryInfo : OpenError: (w.x.y.z:String) [], PSRemotingTransportException + FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken I guess my next move is to use the PSDiagnostics module to see if I can get a more detailed error message from the WSMan trace... Looks tedious. Edit: Found the issue via PSDiagnostics logs on the server machine. My session config defined a psm1 to import to the session, and it was sitting on the desktop of my admin account while I was testing. Moved it to a location that any valid user would have access to and it works! Eggnogium fucked around with this message at 20:10 on Oct 2, 2015 |
# ? Oct 2, 2015 17:29 |
|
Eggnogium posted:SDDL is gibberish to me so I used -ShowSecurityDescriptorUI. None of the guides I've found said which permissions were required so I granted Full Control. Yay! Glad you got it working. The minimum permissions you need (if you want to limit it, and you should), are Read and Invoke.
|
# ? Oct 3, 2015 07:56 |
|
Okay, this is a huuuge problem, so I need some help in how to tackle it. Only read ahead if you really want to help me We have a list that looks like this in Excel / CSV Our main objective - get contained groups of users and internetaddresses. We're doing a migration and so we need to migrate shared mailboxes and their users at the same time. That's the objective with this script. I'm dealing with a problem right now - I want there to be an object like this: Object Internetaddress : {a@contoso.com, b@contoso.com, c@contoso.com} Members: {{User1, User3, User7, User10, User4, User100, User5, User2, User8}, {User10, User8, User5, User2, User20, User3, User4}, {User40, User100, User10}} Things to note: Users are not repeated in any array and the positions match the association. Here's what I have right now: code:
However, when I use code:
What am I missing?
|
# ? Oct 6, 2015 15:33 |
|
I'm confused why you can't just pipe this into import-csv. Is there a reason you need a singular array rather than a list of objects that can be treated like an array? I suppose that would get you each field as a string, and you'd have to manually split it up into an array and maybe even make a new object but that still seems easier than what you're trying to do.
|
# ? Oct 6, 2015 19:55 |
|
Running into an issue with importing printers based on a query. I'm restricted to using GWMI to query rather than the Print Management cmdlets since these are being run on Windows 7 clients. The general premise is for each client to have a script (either pushed via SCCM or as a part of logon) that will completely remove all connected network printers, query the local print server, then add all network printers it can find. Removal is the simple part: code:
However, I'm having issues finding something that will allow me to query a print server and pipe the results into an object creation cmdlet. Querying works without issue; the print server and the client workstation have a similar naming convention based on subnet, so we can have a working query using variables extrapolated from the hostname running the client to create the path to the print server that works across multiple locations. code:
New-Object doesn't support piping, and anything piped to it would need to be made from the [wmi]win32_printer context, so from what I can tell something like this: code:
Any help on this would be appreciated, I'm sure I'm missing something obvious but I just can't script anymore today. There seem to be options out there that work with singular printer queues, but none that work enmasse. Wrath of the Bitch King fucked around with this message at 17:41 on Oct 9, 2015 |
# ? Oct 9, 2015 17:29 |
|
Wrath of the Bitch King posted:
Won't work how? Keep in mind that $_ represents a WMI object here, not a string. The value you get when you inject it into the string will be the same as $_.ToString() , but that's not the same thing you'll see if you just let it get written out to the host, which is the value of $_ | Out-String . These could be the same, but often aren't. So really, you need to figure out which property of $_ you want, then use "\\$PrintServer\$($_.PropertyName)". It's not possible for AddWIndowsPrinterConnection to know that you're doing variable interpolation inside the string you passed to it (that step happens before it ever enters that method). Add this inside your loop, write before the New-Object line: code:
|
# ? Oct 9, 2015 18:36 |
|
Seriously, thank you loads. I knew it was something stupid, and I had a feeling it had to do with failing to isolate the property.
|
# ? Oct 9, 2015 19:24 |
|
So over the last two weeks I've been sort of forced to learn Ruby on Rails (RoR). It's made me re-evaluate how SQL access is implemented in Powershell. One of the frustrating things about powershell for me has been dealing with SQL, for example I want/need to monitor a table every 15 minutes for a specific case and then log that event and/or take action, or pull data out of our configuration db to handle pulling servers in/out of our load balancer for code deployments etc etc. Powershell does an awful, awful job of talking to SQL. RoR even takes the actual SQL queries out of the loop entirely. Is there a way to make Powershell + SQL less painful? I guess MS has their LINQ language but I was never able to get that to work and we generally avoid doing anything in powershell with SQL unless it's absolutely necessary (like the load balancer example I gave). Seeing how well RoR talks to the database makes me crazy envious. Was the secret purpose of PS Modules to write the primary language, and hope that the community would come around and build something Rails-ey behind them?
|
# ? Oct 11, 2015 22:45 |
|
Hadlock posted:So over the last two weeks I've been sort of forced to learn Ruby on Rails (RoR). It's made me re-evaluate how SQL access is implemented in Powershell. import-module sqlps Also LINQ isn't a language and it's not specifically for SQL. It stands for Language INtegrated Query. There's LINQ to Entities for Entity Framework, but EF is a shitpile anyway. And I've become convinced that SQL-generating ORMs are almost universally more trouble than they're worth. Powershell is supposed to be more similar to something like Bash than it is to Ruby. Bash doesn't have an ORM, either, because working with databases from a command shell is niche at best.
|
# ? Oct 11, 2015 23:53 |
|
Ithaqua posted:import-module sqlps Does sqlps even work if you're not directly running on a machine with SQL Server installed? I think I tried going that route and found out you can't install sqlps without SQL Server already being on the machine, which was really annoying since our SQL servers are run by a different group and fenced off from my environment. It does work really excellently for DBA work though.
|
# ? Oct 12, 2015 00:38 |
|
Hadlock posted:Does sqlps even work if you're not directly running on a machine with SQL Server installed? Yes. http://guidestomicrosoft.com/2015/01/13/install-sql-server-powershell-module-sqlps/
|
# ? Oct 12, 2015 00:42 |
|
Oh right, I think we came across that too, but it is not backwards compatible with 2008 non-R2 Which is about 90% of my production environment
|
# ? Oct 12, 2015 01:01 |
|
orange sky posted:What am I missing? If you can paste your list example in a format I can copy and paste I will play around with it later tonight, assuming the previous doesn't help or get you on the right track. 12 rats tied together fucked around with this message at 19:39 on Oct 12, 2015 |
# ? Oct 12, 2015 17:11 |
|
Hadlock posted:So over the last two weeks I've been sort of forced to learn Ruby on Rails (RoR). It's made me re-evaluate how SQL access is implemented in Powershell. Well the two languages have entirely different purposes. I mean really, they aren't even both languages. PowerShell is a scripting language/shell environment. RoR is an MVC web platform (rails is the platform, and that's what's abstracting the SQL stuff, Ruby is the language). Before I learned PowerShell I was using Ruby (not rails) for most of my windows scripting, and using SQL with it is just as painful. But I get what you're saying; it feels wrong to use SQL directly in scripts, and it kind of is. My approach to this is usually to separate the concerns. Lately, I've been fond of wrapping SQL databases in a REST API, using an ASP.NET Web API project, with something like Entity Framework as an ORM. This is in C#. Then a server runs IIS and hosts that app, and in PowerShell I either call the REST API directly (Invoke-RestMethod), or even better, I write a PowerShell module that wraps the API, and then provide familiar PowerShell-like cmdlet style functions, like Get-MyAppRecords or whatever). Writing a module also makes it easier to use the underlying .Net objects to make the web requests and do JSON conversion, that way you don't have a dependency on PowerShell 3.0 if your environment is still heavily locked on 2.0. I wasn't going to post about this here for a while since I'm not all that close to a releasable version, but I am working on a project that would simplify some of this. It will be on GitHub when it's ready.
|
# ? Oct 12, 2015 23:11 |
|
|
# ? May 15, 2024 02:48 |
|
Briantist posted:Well the two languages have entirely different purposes. I mean really, they aren't even both languages. PowerShell is a scripting language/shell environment. RoR is an MVC web platform (rails is the platform, and that's what's abstracting the SQL stuff, Ruby is the language). Agreed on most points. I don't agree with writing a WebAPI service to provide a RESTful API for a simple PS script, though -- that turns into a whole deployment and maintenance scenario. Any well-architected, modern application should be able to perform logging and handle error conditions itself without needing an external helper script. Since we're talking about an external helper script, we can assume it's probably a legacy application that's already suffering from spaghetti dependency syndrome. Adding WebAPI on top of that is just throwing another noodle in the pile. For a modern application? Especially one that's public-facing? Absolutely, expose a REST API and write a module for it!
|
# ? Oct 13, 2015 00:18 |