Why is $DebugPreference getting lost in a module? - variables

I have a powershell script and I have set the $DebugPreference to "Continue". However when I call Write-Debug from a module that is called from my script, the $DebugPreference changed to "SilentlyContinue". Why is that? How can I keep $DebugPreference the same as the calling script? Example below
CallingScript.ps1
$DebugPreference = "Continue"
Write-Host "Debug preference: $DebugPreference"
Write-Debug "Checking that debugging works"
Import-Module Logging;
Write-Log "Debug" "Checking that debugging still works!"
Logging.psm1
Function Write-Log
{
param (
[ValidateSet("Error","Warning","Debug","Info")][String]$type,
[String]$logMessage
)
Write-Host "Debug preference: $DebugPreference"
switch($type)
{
"Error" {Write-Error $logMessage;}
"Warning" {Write-Warning $logMessage;}
"Debug" {Write-Debug $logMessage;}
"Info" {Write-Output $logMessage;}
}
}
If I run the script, this is the output:
PS > .\CallingScript.ps1
Debug preference: Continue
DEBUG: Checking that debugging works
Debug preference: SilentlyContinue
PS >

As JPBlanc's link in his comment explains: It is a variable scope issue. The module's scope chain goes directly to the global scope and not through any script scopes. Even if it is imported from a script.
Your code will work if you set $DebugPreference from your script in the global scope, but of course this has influence on more than just your script.
$global:DebugPreference = "Continue"
Another solution in this specific $DebugPreference case is to use the -Debug parameter to pass it along. The downside is that you will have to do this with every command you call.
Write-Log "Debug" "Checking that debugging still works!" -debug:$DebugPreference
A third solution would be to set $DebugPreference at the module level.
$m = Import-Module Logging -PassThru
& $m {$script:DebugPreference = 'Continue'}

Related

Azure automation runbook Completed before running the code

I have a situation where in the Azure automation runbook results in 'Completed' state and does not run the 'actual' code. I have pasted the code below. It creates a Event Hub inside a Namespace. The code works perfectly executing in local machine but it does not execute in Runbook.
I have written a 'write-output "Declaring local variables for use in script"' --> to check if the printing is working. However, the code is not going beyond that. I am sure, I am missing some thing. Kindly help me.
Param(
[Parameter(Mandatory=$true)]
[string] $NameSpaceNameName,
[Parameter(Mandatory=$true)]
[string[]] $EventhubNames,
[Parameter(Mandatory=$true)]
[string] $ProjectId,
[Parameter(Mandatory=$true)]
[int] $PartitionCount,
[Parameter(Mandatory=$true)]
[string]$Requested_for,
[Parameter(Mandatory=$true)]
[string]$Comments
)
## Login to Azure using RunAsAccount
$servicePrincipalConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
Write-Output ("Logging in to Az Account...")
Login-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
write-output "Declaring local variables for use in script"
## Declaring local variables for use in script
$Creation_date = [System.Collections.ArrayList]#()
$ResourceGroups = Get-AzResourceGroup
$provided_name_space_exists = $false
## Change context to Platform subscription
select-azsubscription -subscription "GC302_Sub-platform_Dev"
## Create Event Hub
foreach($Resourcegroup in $ResourceGroups){
Write-Host("Processing the Resource Group: {0} " -f $Resourcegroup.ResourceGroupName)
$EventhubNameSpaces = Get-AzEventHubNamespace -ResourceGroupName $ResourceGroup.ResourceGroupName
# Iterate over each Namespace. Fetch the Resource Group that contains the provided Namespace
foreach($EHNameSpace in $EventhubNameSpaces){
if($EHNameSpace.Name -eq $NameSpaceName){
$provided_name_space_exists = $true
Write-Host ("Found the provided Namespace in resource group: {0}" -f $Resourcegroup.ResourceGroupName)
Write-Output ("Found the provided Namespace in resource group: {0}" -f $Resourcegroup.ResourceGroupName)
$nameSpace_resource_group = $ResourceGroup.ResourceGroupName
# Fetch the existing Event Hubs in the Namespace
$existing_event_hubs_list = Get-AzEventHub -Namespace $EHNameSpace.Name -ResourceGroupName $nameSpace_resource_group
## Check provided EH for uniqueness
if($existing_event_hubs_list.Count -le 1000){
for($i = 0;$i -lt $EventhubNames.Count;$i++){
if($existing_event_hubs_list.name -notcontains $EventhubNames[$i]){
$EventHub = New-AzEventHub -ResourceGroupName $nameSpace_resource_group -Namespace $EHNameSpace.Name -Name $EventhubNames[$i] -PartitionCount $PartitionCount
$date = $EventHub.CreatedAt
$Creation_date+= $date.GetDateTimeFormats()[46]
}else{
Write-Host ("Event hub: '{0}' already exists in the NameSpace: {1}. skipping this Event hub creation" -f $EventhubNames[$i], $EHNameSpace.Name)
}
}
}else{
Write-Host ("The Namespace - {0} has Event Hubs count greater or equal to 1000." -f $EHNameSpace.Name)
Write-Host ("Please refer the Link for Eevent Hubs quota/limit: 'https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-quotas#event-hubs-dedicated---quotas-and-limits'")
exit
}
}
}
}
# Print a message that Namespace does not exist
if($provided_name_space_exists -eq $false){
Write-Host ("Provided NameSpace: {0} does not exist." -f $NameSpaceName)
exit
}
Screenshot:
You have $NameSpaceNameName in the parameters section of the runbook but later in the runbook at 50th line you have $NameSpaceName which is not the same as mentioned in parameters section. Correct it and then it should work as expected. One suggestion is to always have an else block wherever you have if block to overcome such issues in future.

Error while executing the perl script and not able to set the Environment Variables

I executed the below perl script,
#!/usr/bin/perl
use strict;
use DBD::Oracle;
use DBI;
my $driver = "Oracle";
my $database = "host=xxxxxx;port=6210;sid=xxxx";
my $dsn = "DBI:$driver:$database";
my $userid = "xxxxx";
my $password = "xxxxx";
#Database Connection
my $dbh = DBI->connect($dsn, $userid, $password,{RaiseError => 1}) or die "$DB::errstr";
my $sth = $dbh->prepare("update collabuser set user_email='aravikum.wipro.com' where user_login='aravikum'") or die "$DBI::errstr";
$sth->execute() or die "couldn't execute statementn$!";
$sth->rows;
#End of Program
$sth->finish();
$dbh->disconnect();
I got the error below:
Can't load '/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: libocci.so.11.1: cannot open shared object file: No such file or directory at /usr/lib64/perl5/DynaLoader.pm line 190.
at perlupdt.pl line 11.
Compilation failed in require at perlupdt.pl line 11.
BEGIN failed--compilation aborted at perlupdt.pl line 11.
on googling, i got an answer like running the below export commands fixed the issue. so, i executed and it worked fine,
export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export LD_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib:$LD_LIBRARY_PATH
export PATH=/usr/lib/oracle/11.2/client64/bin:$PATH
But, i cant execute the above commands each and every time when i login to putty,
I decided to put this export inside the script so added these at the starting of the script,
$ENV{"ORACLE_HOME"} = '/usr/lib/oracle/11.2/client64';
$ENV{"LD_LIBRARY_PATH"} = '/usr/lib/oracle/11.2/client64/lib:$LD_LIBRARY_PATH';
$ENV{"PATH"} = '/usr/lib/oracle/11.2/client64/bin:$PATH';
But I am getting the above stated error, please suggest a solution to import these commands inside my perl script.
After setting the above export commands in the etc/profile and etc/bashrc and adding as an .sh file under etc/profile.d fixed the issue.

bin/behat not accepting arguments

While attempting to fix another issue I'm having (Behat tests not running on CircleCI) I noticed that any argument I provide to bin/behat is not accepted. For example, if I run bin/behat -h, I don't get the help options. It just runs my tests. If I rename my behat.yml file to behat-test.yml, and try to run bin/behat --config behat-test.yml, I get an error stating that the FeatureContext can't be found. No matter what I type after bin/behat it is ignored and it runs my tests.
I added a var_dump in Behat's Application.php file and it is not capturing the arguments and prints an empty array. e.g.
public function run(InputInterface $input = null, OutputInterface $output = null)
{
if (null === $input) {
$input = new ArgvInput();
}
var_dump($input);
Turns out, due to the nature of the CMS I'm working with I had to fudge some $_SERVER variables, and I had hard-coded $_SERVER['argv'] = array(), and forgot about it, which explains why no arguments were working.

kvm.ps1 cannot be loaded because running scripts is disable on this system

I am trying to run the Asp.net vNext sample application.
But when i try to execute the command
kvm list
It gives me the error message
kvm.ps1 cannot be loaded because running scripts is disable on this system
I tried to change to execution policy also. But still i am getting the same error.
Try this
execute this command on console
**"powershell Set-ExecutionPolicy RemoteSigned"**,
after that run the commands bellow
$tempPath = Join-Path $env:TEMP "kvminstall"
$kvmPs1Path = Join-Path $tempPath "kvm.ps1"
$kvmCmdPath = Join-Path $tempPath "kvm.cmd"
Write-Host "Using temporary directory: $tempPath"
if (!(Test-Path $tempPath)) { md $tempPath | Out-Null }
$webClient = New-Object System.Net.WebClient
Write-Host "Downloading KVM.ps1 to $kvmPs1Path"
$webClient.DownloadFile('https://raw.githubusercontent.com/aspnet/Home/master/kvm.ps1', $kvmPs1Path)
Write-Host "Downloading KVM.cmd to $kvmCmdPath"
$webClient.DownloadFile('https://raw.githubusercontent.com/aspnet/Home/master/kvm.cmd', $kvmCmdPath)
Write-Host "Installing KVM"
& $kvmCmdPath setup
You could try the powershell command Unblock-File?

System.EnterpriseServices and Powershell Locking dll

I am trying to use System.EnterpriseServices to uninstall a c# com+ component, replace the dll and reinstall the new version.
The problem is that when I get to the line copy-item the script always fails because System.EnterpriseSerivces is locking the destination file. If I break the script up into two sections one that calls UnistallAssembly and a second that does the copy and calls InstallAssembly everything works.
Any ideas for forcing system.enterpriseservices to release dll?
$comRoot = "C:\Comroot\"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.EnterpriseServices")
[System.String]$applicationName = "My App Name";
[System.String]$typeLibraryName = $null;
$objAdmin = new-object -com COMAdmin.COMAdminCatalog
$objAdmin.ShutdownApplication("$applicationName");
$objAdmin = $null
$helper = New-Object System.EnterpriseServices.RegistrationHelper
$helper.UninstallAssembly("$comRoot\$StepName.dll", $applicationName)
$helper = $null
$applicationName = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
"SOURCE : $BranchPath\Steps\$StepName\bin\Debug\"
"DESTINATION : $comRoot"
copy-item "$BranchPath\Steps\$StepName\bin\Debug\*$StepName*" -destination "$comRoot" - force
$helper = New-Object System.EnterpriseServices.RegistrationHelper
$helper.InstallAssembly("$comRoot\$StepName.dll", [ref] $applicationName, [ref] $typeLibraryName, [System.EnterpriseServices.InstallationFlags]::ConfigureComponentsOnly);
"Install Complete <$typeLibraryName>"
Read-Host "Press any key to exit"
I wonder if it is possible the uninstall isn't finished by the time you attempt the copy? That is, is the call to UninstallAssembly sync or async? One way to work around "file in use" issues is to attempt to rename the file using a tool like the SysInternals MoveFile.exe and then install the new version.