|
Briantist posted:Yeah modules are the way to go. Ensure they are well-formed modules with proper paths and manifests and then put them in a path that's included in variable cheese-cube mentioned, that way you can import them by name only. Sure, being able to import modules by name instead of path is nice but I was more talking about the implicit importing feature introduced in PowerShell 3.0 which loads modules automatically meaning that you don't have to call Import-Module. As long as your module shows up in the output of Get-Module -ListAvailable it can be automatically imported. Outside of scripting this feature is especially useful if you do a lot of administration and whatnot via the CLI.
|
# ? Feb 16, 2017 19:30 |
|
|
# ? May 15, 2024 03:53 |
|
Briantist posted:Yeah modules are the way to go. Ensure they are well-formed modules with proper paths and manifests and then put them in a path that's included in variable cheese-cube mentioned, that way you can import them by name only. Oh dag, that's cool as hell. I'm definitely going to look into breaking the existing scripts down into future modularity like this. I'll probably also have to dive into the manifest files for my new hire script since it involves a lot of csv lookups and exporting stuff, and there's currently a lot of $PSScriptRoot scattered around a couple of other ones. Inspector_666 fucked around with this message at 19:39 on Feb 16, 2017 |
# ? Feb 16, 2017 19:35 |
|
cheese-cube posted:Sure, being able to import modules by name instead of path is nice but I was more talking about the implicit importing feature introduced in PowerShell 3.0 which loads modules automatically meaning that you don't have to call Import-Module. As long as your module shows up in the output of Get-Module -ListAvailable it can be automatically imported. Outside of scripting this feature is especially useful if you do a lot of administration and whatnot via the CLI. It's definitely useful in the CLI; I never rely on it in scripts.
|
# ? Feb 16, 2017 20:02 |
|
Briantist posted:It's definitely useful in the CLI; I never rely on it in scripts. Agreedo 100%. I always explicitly load modules in scripts and include exception handling to ensure that they do actually load.
|
# ? Feb 16, 2017 20:04 |
|
cheese-cube posted:Agreedo 100%. I always explicitly load modules in scripts and include exception handling to ensure that they do actually load. I either use #Requires -Module or Import-Module Module -ErrorAction Stop and leave it at that.
|
# ? Feb 16, 2017 20:12 |
|
Briantist posted:Do you do a whole try {} catch {} around it? Doesn't #Requires always stop the script if it fails? Seems like anything else would kind of defeat the purpose.
|
# ? Feb 16, 2017 20:17 |
|
Briantist posted:Do you do a whole try {} catch {} around it? Wow OK so I'll sheepishly admit that I've never known about #Requires statements in PS however I'll definitely be using from now on. It's true, you learn something new everyday! Previously I've just been using try {} catch {} around Import-Module, primarily because I write scripts which are meant to run unattended so I need to catch exceptions and write them out to a log file before throwing them.
|
# ? Feb 16, 2017 20:21 |
|
Inspector_666 posted:Doesn't #Requires always stop the script if it fails? Seems like anything else would kind of defeat the purpose. cheese-cube posted:Wow OK so I'll sheepishly admit that I've never known about #Requires statements in PS however I'll definitely be using from now on. It's true, you learn something new everyday! I've seen people do try/catch around Import-Module but I figure if your script has to exit anyway, why not just let it terminate? I guess the log file scenario is one reason, though these days I've set up automatic transcription through group policy so I tend to avoid writing logs manually (that really needs v5 to work well though). But yeah as Inspector_666 said, #Requires will prevent the script from executing so don't use if for your use case unless you don't need to log those errors.
|
# ? Feb 16, 2017 21:04 |
|
Briantist posted:I guess the log file scenario is one reason, though these days I've set up automatic transcription through group policy so I tend to avoid writing logs manually (that really needs v5 to work well though). The majority of exceptions don't really provide much info to go on so I like to write $Error[0] plus some context to the log file. Regarding WMF 5.0 as I mentioned earlier in the thread there's a lot of stuff that has been deemed incompatible with WMF 5.0 (https://msdn.microsoft.com/en-us/powershell/wmf/5.0/productincompat) so you're pretty much stuck with 4.0 unless you're in a green-fields latest and greatest environment.
|
# ? Feb 16, 2017 21:11 |
|
cheese-cube posted:Regarding WMF 5.0 as I mentioned earlier in the thread there's a lot of stuff that has been deemed incompatible with WMF 5.0 (https://msdn.microsoft.com/en-us/powershell/wmf/5.0/productincompat) so you're pretty much stuck with 4.0 unless you're in a green-fields latest and greatest environment. WMF 5.1 is out but it doesn't seem to have such a list. I don't at all run in a greenfield environment but the vast majority of our servers can use 5/5.1. I think it's just Lync/Skype servers that we're not upgrading it on so we mostly get the benefits. YMMV of course. Also if you run a script from a 5+ machine that remotes into an earlier machine to do work there, the output still comes back to the calling session and would get logged.
|
# ? Feb 16, 2017 22:30 |
|
I'm trying to add content to a file, but am hitting a snag with my "-join"ed content being split into new lines at the join points. Eg:code:
code:
Advice?
|
# ? Mar 5, 2017 20:54 |
No idea about that, but I've always just used the + operator to assemble strings when needed. Or string interpolation to glue contents of variables into strings.code:
|
|
# ? Mar 5, 2017 20:58 |
|
Newf posted:I'm trying to add content to a file, but am hitting a snag with my "-join"ed content being split into new lines at the join points. Eg: Needs to be in parenthesis. code:
|
# ? Mar 5, 2017 21:01 |
|
nielsm posted:No idea about that, but I've always just used the + operator to assemble strings when needed. Or string interpolation to glue contents of variables into strings. code:
|
# ? Mar 5, 2017 21:06 |
|
anthonypants posted:Yeah, I would definitely leave out the -Join operator Depends on what he's doing, in the example it doesn't matter, but if he's actually trying to join something more complex with a delimiter he needs it.
|
# ? Mar 5, 2017 21:16 |
|
PBS posted:Depends on what he's doing, in the example it doesn't matter, but if he's actually trying to join stuff with a delimiter he needs it.
|
# ? Mar 5, 2017 21:17 |
|
Thanks all. I'm forever misplacing parenthesis in PS.
|
# ? Mar 5, 2017 21:20 |
|
I am trying to update ProxyAddresses attribute on multiple AD users. The idea is, if user has default Proxy Address set (denoted by uppercase SMTP:) add new one as an alias (with lowercase smtp:), and if ProxxyAddresses is not set, or in lowercase, add it in uppercase. This is what I have so far:code:
I must be missing something painfully obvious, but I can't find out what.
|
# ? Mar 10, 2017 14:01 |
|
For starters, try changing to clike instead. I don't really see any glaring issues. My guess is you're using match incorrectly, match uses regex. I've never really taken the time to figure out match, but it is generally faster than like.code:
Tip, use regexr to test your regex. PBS fucked around with this message at 16:24 on Mar 10, 2017 |
# ? Mar 10, 2017 16:16 |
|
PBS posted:For starters, try changing to clike instead. I don't really see any glaring issues. My guess is you're using match incorrectly, match uses regex. I've never really taken the time to figure out match, but it is generally faster than like. Match will return $true if a value is found anywhere in the string. I tested the output of cmatch, and it returns the correct values.
|
# ? Mar 10, 2017 16:45 |
|
The Claptain posted:I am trying to update ProxyAddresses attribute on multiple AD users. The idea is, if user has default Proxy Address set (denoted by uppercase SMTP:) add new one as an alias (with lowercase smtp:), and if ProxxyAddresses is not set, or in lowercase, add it in uppercase. This is what I have so far: ProxyAddresses is multi-valued (it's an array). -Add adds an attribute to the AD object, but it won't add a value to a multi-valued attribute. The attributes value itself must be complete, so you will have to create / modify the array itself in code before passing it to Set-ADUser. This also means that your check is not quite doing what you think, but it will still work (mostly). When you use the -match or -like (or most) operators with the left side being an array, instead of returning a boolean value it returns an array containing the items that match. In your case this kind of works, since if there are no entries that match the pattern the result will be an empty array, which will evaluate to false, and an array of any size will evaluate to true. The thing where you have to be careful with that pattern is that it looks for SMTP anywhere in the string it searches. Consider a proxy address like this: smtp:IheartSMTP@example.com That will match your pattern. Instead, anchor it at the beginning of the string using ^SMTP:. Once you've done that, you'll have to (re)construct the addresses array before setting it on the object, at which point you need to use the -Replace operator rather than -Add: code:
|
# ? Mar 10, 2017 17:22 |
|
Hey, I did this a while back and posted about it anthonypants posted:I wrote a script to rename our userPrincipalName and proxyAddresses because we use .local as our tld for everything and we need to move to Office 365. Most of the scripts I found were "just replace the proxyAddresses with 'smtp:samaccountname@domain.tld'!" but a lot of people have alternate email addresses or have changed their last names, so I came up with this monstrosity to just do a find/replace inside of everything instead. I'm probably still reinventing the wheel here, but whatever.
|
# ? Mar 10, 2017 17:44 |
|
anthonypants posted:e: sometimes the samaccountname or the proxyaddresses don't have matching upper/lowercase so it can't be in the -clike statement or else nothing gets See Demo: ^SMTP:(?i)EmaiLaDDreSS
|
# ? Mar 10, 2017 18:32 |
|
Briantist posted:If you use -match (even the C or I versions), you can make part of the regex case insensitive (or sensitive), by using flags inside the regex, if you must do it in one match. But I think it's clearer to do 2 compares like you're doing.
|
# ? Mar 10, 2017 18:47 |
|
anthonypants posted:I like being clear, and I think it's important, which is one of the reasons why I try to match capitalization and type out all the cmdlet names instead of using aliases. I was just pointing it out because that feature of regex is not as well known, and in other situations doing 2 matches is not the same.
|
# ? Mar 10, 2017 19:11 |
|
Briantist posted:ProxyAddresses is multi-valued (it's an array). -Add adds an attribute to the AD object, but it won't add a value to a multi-valued attribute. The attributes value itself must be complete, so you will have to create / modify the array itself in code before passing it to Set-ADUser. I thought I was doing something wrong with regards to multi-valued attribute, and not with the rest of the script. [/quote]This also means that your check is not quite doing what you think, but it will still work (mostly). When you use the -match or -like (or most) operators with the left side being an array, instead of returning a boolean value it returns an array containing the items that match. In your case this kind of works, since if there are no entries that match the pattern the result will be an empty array, which will evaluate to false, and an array of any size will evaluate to true. The thing where you have to be careful with that pattern is that it looks for SMTP anywhere in the string it searches. Consider a proxy address like this: smtp:IheartSMTP@example.com That will match your pattern. Instead, anchor it at the beginning of the string using ^SMTP:.[/quote] I was aware of this, but left it aside "I'll whink about it when I get the rest of the script working". quote:Once you've done that, you'll have to (re)construct the addresses array before setting it on the object, at which point you need to use the -Replace operator rather than -Add: code:
e: Nevermind, I'm dumb and this works perfectly. I was trying to add the same proxy address. Don't script without morning coffee. Thanks for the help! anthonypants posted:Hey, I did this a while back and posted about it I should have searched the thread more, so thank you, too. The Claptain fucked around with this message at 10:03 on Mar 13, 2017 |
# ? Mar 13, 2017 09:30 |
|
anthonypants posted:I like being clear, and I think it's important, which is one of the reasons why I try to match capitalization and type out all the cmdlet names instead of using aliases. Using full cmdlet names and parameter values will cost you nothing and often times save you debugging. Edit: re this SMTP proxy address malarkey, pretty sure there's a native EMS cmdlet for managing addresses.
|
# ? Mar 13, 2017 13:18 |
I can't remember the terms to search for here, so can't find an answer... I have a bunch of WMI objects I want to pass to Remove-WmiObject -Confirm, but the identity displayed for each is useless to the operator. Is there a way to override the "short display string" or whatever it's called for an object? code:
pre:Confirm Are you sure you want to perform this action? Performing the operation "Remove-WmiObject" on target "\\machine\root\cimv2:Win32_UserProfile.SID="S-1-5-18"".
|
|
# ? Mar 20, 2017 14:12 |
|
nielsm posted:I can't remember the terms to search for here, so can't find an answer... That output is the result of what is being passed to the method used for confirmation. Without changing the target yourself, I don't think you can change what's displayed for the confirmation without modifying those cmdlettes. The easiest solution is probably to iterate though the objects and write information about the object before the confirmation dialog appears.
|
# ? Mar 20, 2017 15:14 |
PBS posted:That output is the result of what is being passed to the method used for confirmation. Without changing the target yourself, I don't think you can change what's displayed for the confirmation without modifying those cmdlettes. I think it uses obj.ToString() to get the identity shown, but really no idea. I'm not sure if it's even documented. The problem with manually iterating over the objects is that you can very easily break "Yes to All" and "No to All" which are important to have in this use case. But I think maybe writing a cmdlet of my own that just wraps Remove-WmiObject but somehow causes a more useful object identity to be printed, could work.
|
|
# ? Mar 20, 2017 19:55 |
|
nielsm posted:I think it uses obj.ToString() to get the identity shown, but really no idea. I'm not sure if it's even documented. True, but if you're worried about deleting a system account or something why would you want to select yes to all, and if you do want to why even bother with -confirm? code:
|
# ? Mar 21, 2017 01:16 |
|
Hello gentlegoons, I just got referred to this thread as someone who is looking to expand on my use of AutoHotKey with a more powerful tool. I've read through the op and noticed that most of Adaz's examples (from 2010) look to be regarding running scripts to do things on a server or on the administrative side of IT work. I work on a support desk at a software engineering company and do a number of repetitive tasks in Salesforce and in our proprietary software. I have used AHK to make ~40+ scripts to automate my most common/most repetitive work in Salesforce, but I dont feel like AHK is robust enough to what I would want it to do on the front-end of the software I support - is Powershell something I should be looking into? Or am I a bad that needs to learn more about AHK? On a side, but related note, I am making a push to join development at my company as a QA, and one of the goals on that side is to try to start to automate some of the QA processes, and I figure knowing something more advanced than AHK would be wise - can Powershell automate clicking through webpages and completing actions in a website? Can it be programmed to be intuitive at all, such as with something akin to if/then statements? AAAAA! Real Muenster fucked around with this message at 14:24 on Mar 23, 2017 |
# ? Mar 23, 2017 13:53 |
|
I had to Google it but I presume AHK = AutoHotKey? I wouldn't recommend using PowerShell to do simulated transactional stuff like you're already doing with AHK. I've never used Salesforce personally but it seems strange that you're using AHK with it for the purpose of automation. Surely they have an API that you can hook into? Regarding your last question, PowerShell is a functional language so control structures like if/else are fully supported.
|
# ? Mar 23, 2017 14:24 |
|
cheese-cube posted:I had to Google it but I presume AHK = AutoHotKey? I wouldn't recommend using PowerShell to do simulated transactional stuff like you're already doing with AHK. I've never used Salesforce personally but it seems strange that you're using AHK with it for the purpose of automation. Surely they have an API that you can hook into? I dont have much tech background or training before I got this job (I dont have a college degree), so working with an API or more advanced scripts is beyond my knowledge at this point, but I am obviously trying to learn and do more.
|
# ? Mar 23, 2017 14:34 |
|
AAAAA! Real Muenster posted:Hah, yeah, I should have spelled that out, it is AutoHotKey, sorry about that. I use it because many of the cases I work in Salesforce are repetitive and 1) I'm lazy 2) I was getting carpel tunnel manually entering up to two dozen clicks/interactions I do on each of the 50+ cases I have to work in a day. It is mostly just data entry into fields that either require input in each case, or the fields default to the wrong thing because we have not had a Salesforce admin in over 2 years. I taught myself AHK one weekend and now I am the highest case closer on my team and spend all this newfound free time doing Useful Things, like becoming the leading expert in the company about our really broken and lovely product (despite being a level 1 ), playing Ping Pong, and reading threads on SA. From the sound of it you're already smashing things by taking advantage of AHK so I reckon the next step is to learn a programming language which will allow you to interface with Salesforce directly using their APIs. As I said before I have zero experience with Salesforce however it looks like they have multiple APIs available. This means you could probably learn any language and then use that effectively with the product. PowerShell is an option here however it's not exactly designed for this kind of work and I suspect that other languages have libraries available which make things much easier. As to choosing a language I can't really comment as I pretty much only work with PS and .NET. Maybe someone else can point you in the right direction.
|
# ? Mar 23, 2017 14:46 |
|
cheese-cube posted:From the sound of it you're already smashing things by taking advantage of AHK so I reckon the next step is to learn a programming language which will allow you to interface with Salesforce directly using their APIs. As I said before I have zero experience with Salesforce however it looks like they have multiple APIs available. This means you could probably learn any language and then use that effectively with the product. PowerShell is an option here however it's not exactly designed for this kind of work and I suspect that other languages have libraries available which make things much easier. As to choosing a language I can't really comment as I pretty much only work with PS and .NET. Maybe someone else can point you in the right direction. Powershell's webserviceproxy is top notch, would probably work pretty well for this. It's not a good choice if the service descriptions are hidden behind an authentication scheme though.
|
# ? Mar 23, 2017 15:11 |
|
https://www.jbmurphy.com/2016/07/25/connecting-to-the-salesforce-rest-api-using-powershell/ I'd bet a lot of your problems have already been figured out, just stick "Salesforce PowerShell" into your search engine of choice. I'd also bet none of it looks like very clean PowerShell so it's going to be a hard thing to start with. edit: Don't get too discouraged. These things are worth learning in general, and you've already experienced the joy of turning a monotonous data manipulation task into a script that you just run while you get coffee and waste your employers time. thebigcow fucked around with this message at 18:13 on Mar 23, 2017 |
# ? Mar 23, 2017 18:11 |
|
thebigcow posted:https://www.jbmurphy.com/2016/07/25/connecting-to-the-salesforce-rest-api-using-powershell/ I am, as cheese_cube so aptly put it, smashing things in Salesforce already, so that issue is essentially tackled, though I wouldnt mind upping my game even more, so my concern is getting some automation for the tasks I do in the proprietary software, which is not as manipulatable with AutoHotKey (to my knowledge). I think the biggest thing stopping me on our software when it comes to AHK is the issue of pages taking time to load - if salesforce starts its script before the page loads its hosed from the start and I have to wait for it to finish thrashing about before I can try again. And writing a separate script for each page would take too many keys.
|
# ? Mar 23, 2017 18:54 |
|
Powershell can do a lot, but I'd start looking at different tools. Check out Selenium for the web browser stuff http://www.seleniumhq.org/
|
# ? Mar 23, 2017 19:44 |
|
|
# ? May 15, 2024 03:53 |
|
I've automated some web stuff with Powershell, but it was all stuff like Press tab two times, fill in field, press tab four times, fill in field, and so on. Other tools that make it easier are probably what you want.
|
# ? Mar 24, 2017 21:20 |