How do I create persistent path variables? - powershell

I've found that the $HOME variable can be rather useful for keyboard-only navigation in PowerShell. It would be nice to have a number of shortcuts stored as persistent path variables that can be accessed using the same syntax. I've seen the method $env:MyTestVariable = "My temporary test variable." but the result isn't persistent and still has to be accessed by typing $env:MyTestVariable which is not as succinct as the desired $MyTestVariable.
How can I create such variables and control what level has access to them (aka User, Machine, and Process)?

Related

What flag to be used if I've used variables declared at collection scope in tests?

I've used variables at environment, gloabl & collection level scope in my tests. I'm aware of the flags to be used for environment & gloabl level scope i.e. -e & -g respectively.
I'm not able to find flag to be used to pass the collection level variables json file in command line to execute my postman automated tests in newman.
Please help me out.
The collection-variables are part of the collection. They're suitable for driving tests in single-enviroments.
I'm using them very rarely and only collection-related for the inner logic of my scripts, that is not environment related (e.g. constants as ISO-Codes).
If it becomes necessary to drive the same collection in different configs, i shift my variables to globals or env variables, depending on the use-case.
You can finde more details about this topic in
https://learning.postman.com/docs/sending-requests/variables/#variable-scopes

Delete variables named in an "unconventional" way

A while ago I was reviewing some legacy code, and I incurred in the following issue: the developer create many variables starting with a dot (like .variable1), syntax reserved to define namesspaces.
When quizzed about the use of that convention, he replied that essentially that was a way to create global variable within the scope of a function - what in Python you would achieve doing the following:
def define():
global a
a = 2
define()
print(a)
In q, that translated in something like this:
f1:{.b1:2;}
f2:{b1:2;}
f1[] / this creates a variable .b1, which you can use globally
f2[] / this creates a variable b1 within the scope of the function, not usable outside
While my preference would have been to create a global variable using a namespace (something like f1:{.my_namespace.b1:2;}), the code was doing its job without any issues.
The problem arises if I want to delete the global variable defined which starts with a dot (.b1 in the case just described), given that approaches like
delete .b1 from `.
do not seem to work. All the references I was able to find (like this) suggest that namespaces cannot be delete, which would imply these unproperly defined variable will stay there.
To be clear, the problem is not about how to delete variables from namespaces, but to delete those namespaces which are used as variables - if possible at all.
Any ideas?
Based on your question, you want to delete variables from a namespace. You can do this by running:
delete b1 from `.my_namespace
Which is also explained in the link you pasted.
What you can't do is actually delete the reference to my_namespace.
As a side note you can also set variables globally in the root namespace using the set keyword:
{`var set 2}[]
Which will let you avoid having to create single use namespaces.

Is there a way to use VSTS Variable Groups per environment?

I'm moving my configuration from using web.config transforms to being based on VSTS variables. I get process variables, you define a variable, pick an environment, and you're good to go. I also see "Variable Groups", these seem great, have KeyVault integration, and overall seem like a much better option.
But...I don't see a way to bind a Variable Group to a specific environment in my VSTS release process. I can't honestly see how these would be any use to me without this feature.
I've experimented with one workaround, but it didn't work. I tried:
Naming my variable group & variables with an environment prefix e.g.
Variable Group Name="Production ConnectionStrings"
Variable name="Production_LoggingConnectionString"
I thought once I linked the "Production_ConnectionStrings" variable, I could reference $(Production_LoggingConnectionString) from within a standard Process variable, but this didn't work.
I think I could come up with some powershell that would do something like the above and set variables, but this seems a bit too custom for me.
Does anyone else have an idea that I can use variable groups per environment, easily, without waiting around for VSTS to build this feature (if ever). Btw, if you want this feature, there is a suggestion here you can upvote: Make it possible to link a variable group to a specific environment in a release definition
This has now been implemented in VSTS variable groups as scopes. Go to your release definition -> Variables -> Variable Groups -> Link variable group, and you get the link window as below, where you can choose the scope to be either release or one or more of your environments!
I did not manage to find any release information on this feature, I just stumbled upon it as I was tweaking my releases.
I ended up using a powershell script to define my process variable based on the variable groups, it works great.
Let's say I want a variable named "LoggingConnectionString" and this has different values per environment
Steps:
Define a Variable group, e.g. "SharedLoggingVariables"
Inside this Variable group, define a variable/value for each environment, e.g. "LoggingConnectionStringDev", "LoggingConnectionStringProduction"
Back in your Process Variables for the Build/Release, make SURE you don't have a variable named "LoggingConnectionString", otherwise this will overwrite the value coming from the variable group
In your Release process, create a Powershell inline script at the beginning of the Agent with the following code
Param(
[string]$LoggingConnectionString
)
Write-Host "##vso[task.setvariable variable=LoggingConnectionString]$LoggingConnectionString"
Pass your variable group as an argument to this inline powershell, e.g.
-LoggingConnectionString "$(LoggingConnectionStringDev)"
The final powershell step should look something like this:
During release, the powershell will set your process variable from the variable groups. If powershell isn't an option for you, there are other options
No, there is no way to use variable Groups per environment.
As the user voice you linked, you can vote and follow up for the suggested feature.
The work around for now is using environment variables to overwrite the variables in variable Group.
Assume the variable LoggingConnectionString with the value Server=myDB in variable group need to be used both for Dev environment and staging environment. But for staging environment, it needs to use another value (such as Server=stageDB) from the variable LoggingConnectionString. So you can add the an environment variable LoggingConnectionString with the value Server=stageDB for staging environment.
When the variable $(LoggingConnectionString) is used in Dev environment, it will use the value (Server=myDB) defined in variable group.
When the variable $(LoggingConnectionString) is used in staging environment, since the variables both defined in environment variable and variable group, it will use the value (Server=stageDB) defined in environment variable.

Worksession Variables - MATLAB

I'm writing a series of MATLAB functions which communicate with a server through urlread. Each function in this package that makes this call requires an authentication username and key.
I would rather not require the user to pass in the username and key when calling every function. Instead, I prefer to have a signin(username, key) function that sets/saves these variables in such a way that each function in this package can recall.
My solution right now is for signin.m to save username and key to a temporary file and to modify finish.m to erase this temporary file when MATLAB closes. Each function in the package would load these variables from that temporary file. However, if someone force quits MATLAB, this temporary file will not be erased (right?).
Another solution was to have signin save username and key as global variables. However, if a user calls clear all, these variables will be removed the workspace and the user will need to call signin again (which is a nuisance).
Is there some way to set 'session' variables that are global and are not removed with a clear all command? Any other suggestions?
You might consider the preferences feature of MATLAB. It works with the functions setpref, addpref, rmpref, and getpref. I use these tools in a few applications, and they work nicely.
One minor problem is if you will be calling these tools frequently. Since getpref uses a read from a disk file to access the prefs, it is not as fast as it might be. So IF you must have the absolute maximum speed due to frequent calls, then a mixture of persistent variables seems to work well for me. Thus, I have a function that I use to access the preference in question. It contains the pref in a persistent variable. If this is the first time the pref is queried, then that persistent variable will be empty, so I do a getpref call to fill it. (This is a nice feature, since the pref will persist across MATLAB sessions.) When you need to change the variable, do a setpref too.
You're almost there. A few useful features:
persistent
First, you should be using persistent variables rather than global variables. They are like globals, but scoped to a single function. They're just better.
mlock
Run mlock within a function to prevent the clear or clear all command from clearing data associated with that function.
So, for example, you could define a quick function to help a username and key within a Matlab sessionb as follows:
function [name, key] = credentials(varargin)
persistent USERNAME KEY
if nargin==3 && ischar(varargin{1}) && strcmpi(varargin{1},'set')
USERNAME = varargin{2};
KEY= varargin{3};
mlock;
else
name = USERNAME;
key = KEY;
end
Then you could use it like this:
%First, set the credentials
credentials set SOMEUSERNAME SOMEKEY
% .... do some work ....
clear %As part of your work, clear all variables
% .... do some more work ....
%Get the credentials later
[name, key] = credentials;
Another alternative is the official startup.m file and the related Startup Folder. These could be used to do pretty much anything, including the other solutions provided.

Best way to using Global Variables in PowerShell?

I want to use variables over PowerShell instances away.
(I know that global variables are not nice)
Is this the best way to define a variable over instances in PowerShell? Other ideas?
($global:variable is not over PowerShell instances away)
[Environment]::SetEnvironmentVariable("TestVariable", "Test value.", "User")
[Environment]::GetEnvironmentVariable("TestVariable","User")
Yes. Other options would be to:
Write/read a hashtable to a settings file using Export/Import-CliXml.
Stash information in the user's registry hive.
But adding a user environment variable is also a good way to go and the way you suggest is what is needed for the environment changes to survive exiting the current PowerShell session.