I am encountering several situations where, in a Chef recipe with powershell_scipt, a command appears to fail, whereas if I run the same command in powershell outside of Chef, the same command works.
The two in particular are "regedit", which I am trying to use to set a key for app compatibility and the other is "net use z:...." to created a mapped drive. Both of these seem to work fine if I run them in powershell, but if I use them inside a recipe inside powershell_script, they don't appear to do anything.
So I'm wondering is this because Chef runs commands that are inside powershell_script at some lower privilege level?
Also if so, how do I change it so that the regedit and net use would work?
Thanks,
Jim
EDIT 1: This seems to work for adding the registry entry I needed:
registry_key "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags" do
values [{
:name => "{2b9034f3-b661-4d36-a5ef-60ab5a711ace}",
:type => :dword,
:data => 00000004
}]
action :create
end
That prevents the compatability popup that I am getting when we run the Sharepoint installer.
EDIT 2: I hope that this is ok, but for the record and more visibility and hope that I remember this, I found this re. mapping drives in Windows and Chef:
Mount windows shares on a windows node with Chef
and:
https://tickets.opscode.com/browse/CHEF-1267
I haven't tried that yet, but that seems like the answer to my drive mapping need.... hopefully..
The chef client service runs as Local System (SYSTEM) by default.
In Windows, that user has full privileges on the local system, like root basically, but on the network it authenticates as the computer object.
So it you are trying to use regedit to change something in for example HKEY_CURRENT_USER then you need to remember that the code will not see the same "current user" as you will when you run it in interactively. Also, regedit is an .exe; you should really do what you need through the PowerShell providers or .Net objects.
For net use you are trying to map a drive. It's likely that the computer account doesn't have the rights to the share that your user has. Again, net.exe is a separate executable. net use maps a drive to a drive letter (usually) and you shouldn't be doing that in a configuration script, in my opinion. You should access the UNC path directly, but either way I still think that you're probably running into a permissions issue here.
You could change the credentials of the service to use a user account that has all the rights you want, but before doing something like that you should consider changing your workflow to not need that.
Related
As a final step in our AD account creation process that is being moved to a powershell script a few folders need to be created on the filer for users and I am coming unstuck with permissions.
I am just using the basic new-item command to create folder but the locations need unix permissions (775) set before anything can be created. I can't go there and right click in Windows explorer and click new.. and the powershell script is being bounced also due to permissions.
The reasoning from one of the tech guys here is that I am trying to create a sub folder via smb mount from Windows using ntfs permissions. There is no correlation to unix permissions and any of our Linux users won't be able to access / use the location created for them.
Sorry if that is a clumsy way of explaining it, I am not a systems engineer, just the guy trying to translate a whole heap if pearl scripts into a new powershell process.
Thank you
S.
I have to think this is a solved issue but I am just not getting it to work. So I have come to you StackOverflow with this issue:
I have a windows server 2016 machine running in amazon ec2. I have a machine.ps1 script in a config directory.
I create an image of the box. (I have tried with checking noreboot and unchecking it)
When I create a new instance of the image I want it to run machine.ps1 at launch to set the computer name and then set routes and some config settings for the box. The goal is to do this without logging into the box.
I have read and tried:
Running Powershell scripts at Start up
and used this to ensure user data was getting passed in:
EC2 Powershell Launch Tools
I have tried setting up a scheduled task that runs the machine.ps1 on start up (It just hangs)
I see the initializeInstance.ps1 on start up task and have tried to even coop that replacing the line to run userdata with the line to run my script. Nothing.
If I log into the box and run machine.ps1, it will restart the computer and set the computer name and then I need to run it once more to set routes. This works manually. I just need to find a way to do it automagically.
I want to launch these instances from powershell not with launch configurations and auto scale.
You can use User data
Whenever you deploy a new server, workstation or virtual machine there is nearly always a requirement to make final changes to the system before it’s ready for use. Typically this is normally done with a post-deployment script that might be triggered manually on start-up or it might be a final step in a Configuration Manager task sequence or if you using Azure you may use the Custom Script Extension. So how do you achieve similar functionality using EC2 instances in Amazon Web Services (AWS)? If you’ve created your own Amazon Machine Image (AMI) you can set the script to run from the Runonce registry key, but then can be a cumbersome approach particularly if you want to make changes to the script and it’s been embedded into the image. AWS offers a much more dynamic method of injecting a script to run upon start-up through a feature called user data.
Please refer following link for ther same:
Poershell User data
Windows typically won't let a powershell script call another powershell script unless it is being run as Administrator. It is a weird 'safety' feature. But it is perfectly okay to load the ps1 files and use any functions inside them.
The UserData script is typically run as "system". You would THINK that would pass muster. But it fails...
The SOLUTION: Make ALL of your scripts into powershell functions instead.
In your machine.ps1 - wrap the contents with function syntax
function MyDescriptiveName { <original script contents> }
Then in UserData - use the functions like this
# To use a relative path
Set-Location -Path <my location>
# Load script file into process memory
. <full-or-relpath>/machine.ps1
# Call function
MyDescriptiveName <params-if-applicable>
If the function needs to call other functions (aka scripts), you'll need to make those scripts into functions and load the script file into process memory in UserData also.
I have powershell script which is present on chef server to run on remote windows server, how can i run this powershell script from chef server on remote windows server.
Chef doesn't do anything like this. First, Chef Server can never remotely access servers directly, all it does is stores data. Second, Chef doesn't really do "run a thing in a place right now". We offer workstation tools like knife ssh and knife winrm as simplistic wrappers but they aren't made for anything complex. The Chef-y way to do this would be to make a recipe and run your script using the the powershell_script resource.
Does it mean chef is also running on Windows server ?
If yes, why not to use psexec from Windows Ps tools ?
https://learn.microsoft.com/en-us/sysinternals/downloads/psexec
Here is my understanding of what you are trying to achieve. If I'm wrong then please correct me in a comment and I will update my answer.
You have a powershell script that you need to run on a specific server or set of servers.
It would be convenient to have a central management solution for running this script instead of logging into each server and running it manually.
Ergo you either need to run this script in many places when a condition isn't filled, such as a file is missing, or you need to run this script often, or you need this script to be run with a certain timing in regards to other processes you have going on.
Without knowing precisely what you're trying to achieve with your script the best solution I know of is to write a cookbook and do one of the following
If your script is complex place it in your cookbook/files folder (assuming the script will be identical on all computers it runs on) or in your cookbook/templates folder (if you will need to inject information into it at write time). You can then write the .ps file to the local computer during a Chef converge with the following code snippet. After you write it to disk you will also have to call it with one of the commands in the next bullet.
Monomorphic file:
cookbook_file '<destination>' do
source '<filename.ps>'
<other options>
end
Options can be found at https://docs.chef.io/resource_cookbook_file.html
Polymorphic file:
template '<destination>' do
source '<template.ps.erb>'
variables {<hash of variables and values>}
<other options>
end
Options can be found at https://docs.chef.io/resource_template.html
If your script is a simple one-liner you can instead use powershell_script, powershell_out! or execute. powershell_out! has all the same options and features as the shell_out! command and the added advantage that your converge will pause until it receives an exit status for the command, if that is desirable. The documentation on using it is a bit more spotty though so spend time experimenting with it and googling.
https://docs.chef.io/resource_powershell_script.html
https://docs.chef.io/resource_execute.html
Which ever option you end up going with you will probably want to guard your resource with conditions on when it should not run, such as when a file already exists, a registry key is set or what ever else your script changes that you can use. If you truly want the script to execute every single converge then you can skip this step, but that is a code smell and I urge you to reconsider your plans.
https://docs.chef.io/resource_common.html#guards
It's important to note that this is not an exhaustive list of how to run a powershell script on your nodes, just a collection of common patterns I've seen.
Hope this helped.
When running a guest executable in Service Fabric I have noticed that some environment variables do not seem to be mapped to where I would expect them to be.
A few examples of these are that %appdata% didnt resolve to the usual:
C:\Users\\AppData\Roaming
but instead resolved to somewhere deep inside C:/windows
I have also noticed that when running applications using Erlang that the '.erlang.cookie' file is usually placed in the user root:
C:\Users\.erlang.cookie
but instead is trying to be created in C:\Windows
Is there a reason to why these are changed in these ways and currently I am having to make the guest executable not use 'appdata' and grant it administrative privileges using a policy in the application manifest to give it write access to C:\windows to write the '.erlang.cookie'.
That's because services run under the NETWORKSERVICE account by default.
You can do runas, or use the configuration system for settings.
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-application-runas-security
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-configuration
If i create a powershell runspace, either programatically with .NET or just by launching the powershell console; How secure are the scripts/commands that are run?
I'm not speaking about signing scripts, but the actually memory space that the scripts are run in.
I'm worried that if sensitive information is gathered as part of the script (a sql query into a salary database for example) that someone could hack this data out.
I know most people are thinking SecureString at this point, i know about SecureString.... I'm wanting to know specifically about the powershell runspace, not how to store strings securely inside a runspace (lets hope that last sentence didn't just answer my own question).
Specifically :
Are other applications/scripts/whatever able to peer into the runspace and see the commands i'm running?
Powershell script security works by controlling whether or not a script is "allowed" to run on your machine. If you have a machine running an execution policy of "AllSigned", that machine will require the Powershell script to be signed by a trusted certificate.
Scott Hanselman has a really good article on it here.
To my knowledge, your command history isn't permanently saved. You can do a "get-history" to see the commands you've entered in your current session, but it's not like linux/unix where "history" will contain all of the commands you've ever run on the system. As far as other applications being able to "peer into" or query your session, I have no idea.