Perl Script Debugging

Problem scenario:  You are running a Perl program and getting an error "syntax error at cool.pl line x, near ...
Global symbol "$foo" requires explicit package name at cool.pl line x..."

Solution:  Find line x - 1, that is, the line before x.  This line may not have a semicolon.  Semicolons are not needed if the Perl script is one line.  Semicolons are not needed for "sub main" declaration lines with a line with just a brace (either "{" or "}").  Perl debugging may not come as easily as Python or Ruby.  But Perl has numerous features.  

By itself the error 'Global symbol "$foo" requires explicit package name at cool.pl line x...' could be the result of trying to use a variable name that has not been declared.  Make sure you have not made a typo in referring to a declared variable.

Here is a sample Perl script that reads in user input and assigns it to a variable named "$foo":

use strict;
use warnings;

sub main
{
    print "Please enter a string and press enter: ";

    my $foo = <STDIN>;

    print "You entered: $contin";
}

main();

How to Create .EXE Files With PowerShell

Problem Scenario 
You want to package a standalone .ps1 script as an .exe file.  How do you create an executable file that does what a PowerShell script does?


Solution 
Install PowerShell Community Extensions.  Then download this .ps1 file and use it according to the conventions in the comments, near the top, of the script itself,

The usage instructions are in the code.  We found that the -NET40 flag was needed.  Here is an example that assumes four things: 1) you saved the file as "Make-PS1ExeWrapper.ps1" (but this is optional and just an example) 2) the script you want to convert is named "good.ps1" 3) the directory the PowerShell prompt is in is the directory with the two files just mentioned 4) you want the new .exe file to be called good.exe.

>  .\Make-PS1ExeWrapper.ps1 .\good.ps1 .\good.exe -NET40

The actions of good.ps1 will run whenever you double click the good.exe file.  You may transfer good.exe to any Windows machine and run it.

How To Install PowerShell Community Extensions

Problem Scenario:  You want the rich features provided by PowerShell Community Extensions (also known as PSCX).

Solution:
1.  Download the .msi from this link
2,  Double click it. 
3.  Install it by accepting the License Agreement and the defaults. 
4.  Open PowerShell as Administrator. 
5. In PowerShell, Change directories to where it was installed (e.g., C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx). 
6.  Run this command:  import-module .\Pscx.Core.dll

How To Integrate Perl, Ruby, and Python Programs

Problem scenario
You want a Perl program to call a Python program to call a Ruby program to call another Python program.  You are using Linux as the OS.

Solution
Here is a one-line Perl program (course.pl) that calls a Python program:

system( "python /home/ec2-user/cont.py");

Here is a two-line Python program named cont.py.  It invokes a Ruby program.

import subprocess
subprocess.call(['ruby /home/ec2-user/integration.rb'], shell=True)

Here is a one-line Ruby script file named integration.rb (that calls a Python script). 

exec( "python /home/ec2-user/new.py" )

Here is a one-line Python program that prints a basic message, name it "new.py":

print "This final Python script worked!!!"

If each of the above four programs (course.pl, cont.py, integration.rb, new.py) are all in the /home/ec2-user/ directory, just run the Python program like this:  perl course.pl

It will print "This final Python script worked!!!"  This demonstrates integration of three languages with four files and five lines of code. 

Windows Server 2012 Scheduled Tasks Are Not Launching PowerShell Scripts Properly

Problem scenario:  For no apparent reason, Scheduled Tasks are not kicking off PowerShell scripts.  You have configured Scheduled Tasks to launch .ps1 files.The task calls "%windir%\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe" (in the Action tab's "Program/Script" field) with an argument like this "C:\Program Files\good script.ps"

You manually run the scheduled task (by right clicking its name and choosing Run) and the Scheduled Task will seem to run.  In reality, the .ps1 file will not execute (despite having the correct Execution Policy).  You allow the time to pass when it is scheduled to run.  Still there is no evidence that the job runs.  When you look at the Scheduled Tasks you see a column for "Last Scan Result."  Underneath it you see things like this for the Scheduled Task that never really runs:  "The operation completed successfully" or "0x1".  There are no other hints in the history of whether or not previous runs were successful or not.

Root Cause:  The argument has spaces in it.  There is a space between "Program" and "Files".  There is a space between "good" and "script".

Solution:  Change the location of the .ps1 file to not be in a "Program Files" subdirectory.  The path must have no spaces in it.  Change the name of the .ps1 file to eliminate the space.  Reconfigure the Scheduled Task to have the Action tab's argument field point to the new name and location of the .ps1 file.

Miscellaneous:  Microsoft should have a special parsing feature in PowerShell when this command and flag are ran "schtasks /tr".  In the GUI for Task Scheduler, the argument field should detect spaces and not allow the administrator to leave a space in there.  Spaces can exist in the "Program/Script" field of the action of the Scheduled Task.  But the argument cannot have spaces.  If the argument is encapsulated in single quotes and there is a space in the file name, the "Last Scan Result" can speciously say "The operation completed successfully."  If the argument has double quotes or not quotes with a space in its name, the "Last Scan Result" will show "0x1" while the history will not clearly explain what is wrong.

PowerShell Can Throw a SetInfo With 0 Argument(s) Error When Creating a User

Problem scenario
You run a PowerShell script that has a command setinfo.  For example, the script is like this:

        #...
        $userName = 'jdoe'
        $compName = $env:COMPUTERNAME
        $cona = [ADSI]"WinNT://$compName"
        $user = $cona.Create('User',$userName)
        $user.SetInfo()

You get "Exception calling "SetInfo" with "0" argument(s): "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements."

You may go to Administrative Tools -> Local System Security and find the Account password requirements are met.  How do you get around this problem?

Solution
Instead of using $user.SetInfo, try this set of commands:

$userName = 'jdoe'
$secretp = 'sp3shulP@ssw0rd'
net user $userName /add $secretp

System 5 Error in Windows Server 2012

Problem Scenario:  In Windows Server 2012 from a command prompt, you run a .bat file that launches a PowerShell script.  You get an error that says "System Error 5" and "Access is Denied."

Solution:  Open a new command prompt as an Administrator.  Click the Windows button, search for "cmd."  Right click the cmd prompt chose "Open as Administrator."  Try running the .bat file again.

If that does not work, verify the relevant computers have correct time synchronization.

How to Resolve a Puppet Error About Unclosed Quotes

Problem scenario
When running "puppet agent -t" on a Windows server with Puppet Agent installed and configured, you get an error like this:  "Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Unclosed quote after """ followed by ..."

Solution
For the relevant manifest, verify there are no unclosed quotes.  Then verify that you are using double backslashes in any path with a backslash "\".  For example, here are paths that may look unusual, but they are correct in a .pp file:
file { 'c:\\temp\\contint.txt':
         ...}
exec { 'action':
      path => 'c:\\temp\\fun.txt'

Root cause 
Windows can use backslashes as escape characters.  So the parsing of backslashes can cause confusion for Puppet running on Windows.

How to Use Conditional Logic With A Puppet Manifest For Executing a Command

Scenario:  You want an exec command in a manifest to be invoked only if a certain file is on the Windows Server.  You do not want the execution of a command to happen if a file does not exist in a certain location.
Solution:  Incorporate the following lines into your manifest (.pp file).
exec { 'cont_int":
    command => "echo continual > contint.txt",
    provider => powershell,
    path => 'c:\\temp\\',
    onlyif => 'if(test-path c:\\temp\\contualint.txt) {exit 0;} else {exit 1;}',
    }

This is an example of a command that will only execute on a Puppet Agent node if c:\temp\continualint.txt is present.  If it is not found, then it will not run.

How Do You Find Out if The Server Has Puppet Master or Puppet Agent?

Problem scenario
Assuming that you know Puppet is installed, you want to find out if you are on a Linux server that has Puppet Master or Puppet Agent.  This posting applies strictly to Linux or Unix.

Solution
Run this command:
cat /etc/puppet/puppet.conf
Then use "ip addr show" (or ifconfig) to verify the IP address of the server that you are on. 

An alternative way to look for clues, depending on whether or not the server was at one time fully configured for Puppet, you may want to try one of these five commands:
history | grep master
history | grep agent
puppet --version
puppet master --version
puppet agent --version