I have a set of .NET Assemblies (all under the same directory) and some of those contain classes which implement an abstract class. I would like a Powershell script to find all the classes which implement my abstract class, and execute a method on each of them.
Does anybody have an idea on how to do this?
Thanks!
Here's a little function you might want to try.. (I haven't tested it yet, as I don't have any criteria to test this with easily..)
It can be used by supplying the paths (one or more full or relative paths separated by commas) on the command line like this
CheckForAbstractClassInheritance -Abstract System.Object -Assembly c:\assemblies\assemblytotest.dll, assemblytotest2.dll
or from the pipeline
'c:\assemblies\assemblytotest.dll','assemblytotest2.dll' | CheckForAbstractClassInheritance -Abstract System.Object
or with fileinfo objects from Get-Childitem (dir)
dir c:\assemblies *.dll | CheckForAbstractClassInheritance -Abstract System.Object
Tweak as needed..
function CheckForAbstractClassInheritance()
{
param ([string]$AbstractClassName, [string[]]$AssemblyPath = $null)
BEGIN
{
if ($AssemblyPath -ne $null)
{
$AssemblyPath | Load-AssemblyForReflection
}
}
PROCESS
{
if ($_ -ne $null)
{
if ($_ -is [FileInfo])
{
$path = $_.fullname
}
else
{
$path = (resolve-path $_).path
}
$types = ([system.reflection.assembly]::ReflectionOnlyLoadFrom($path)).GetTypes()
foreach ($type in $types)
{
if ($type.IsSubClassOf($AbstractClassName))
{
#If the type is a subclass of the requested type,
#write it to the pipeline
$type
}
}
}
}
}
The same way as you do it with c# but with PowerShell syntax.
Take a look at Assembly.GetTypes and Type.IsSubclassOf.
Related
Is there any plugin of Nagios which can capture information from multiple SNMP agents and will dump snmpwalk information in a certain interval .
It will be better if information will be dumped in JSON format .
Because of the well documented plugin development guidelines, this is something you could easily build yourself!
Let's build one right now. Let's say we have 2 IP addresses, 192.168.1.10 and 192.168.1.11. We'll build a simple plugin using PHP, although you can ideally write it in any language you like.
This plugin isn't going to conform completely to the guides, but it should give you a nice starting point!
#!/usr/bin/php
<?php
// check if we have at least the minimum required output
// (we need at least 1 argument)
if (count($argv) < 2) {
echo <<<USAGE
Usage:
{$argv[0]} <outputfile> <address1>,<snmpcommunity1>,<snmpversion1>,<mib1> <address2>,<snmpcommunity2>,<snmpversion2>,<mib2> ...
USAGE;
exit(1);
}
// prep the data
$hosts = array();
$output = array();
$output_file = '';
for ($i = 1; $i < count($argv); $i++) {
$host = explode(",", $argv[$i]);
// we need exactly 4 elements
if (count($host) != 4) {
// unless of course we are specifying the output file to write the data to!
if (count($host) == 1) {
$output_file = $argv[$i];
continue;
}
echo "{$argv[$i]} IS INVALID. YOU MUST SPECIFY ALL OF: <address>,<snmpcommunity>,<snmpversion>,<mib>\n";
exit(1);
}
$hosts[] = array(
'address' => $host[0],
'snmp_community' => $host[1],
'snmp_version' => $host[2],
'mib' => $host[3],
);
}
// cycle through each host and gather the data
// this may take a while
foreach($hosts as $host) {
$snmpwalk_array = get_snmpwalk_lines($host['address'], $host['snmp_community'], $host['snmp_version'], $host['mib']);
$snmp_array = walk_lines_to_snmp_array($snmpwalk_array);
$output[$host['address']] = $snmp_array;
}
// convert the output array to json and put it in the file!
$json = json_encode($output);
file_put_contents($output_file, $json);
$num_hosts = count($hosts);
echo "OK - {$num_hosts} PROCESSED\n";
exit(0);
// format an array in a sane way from snmp walk output
// this will return an array like:
// [oid][type] = 'Counter32'
// [oid][value] = 0011232
// etc.
function walk_lines_to_snmp_array($walk_arr) {
$snmp = array();
foreach ($walk_arr as $line) {
$oid = convert_snmpwalk_line_to_array($line, $arr);
if ($oid !== false)
$snmp[$oid] = $arr;
}
return $snmp;
}
// return an array of an executed snmpwalk output
function get_snmpwalk_lines($address, $snmp_community, $snmp_version, $mib) {
$cmd = "snmpwalk -c {$snmp_community} -v {$snmp_version} {$address} -m {$mib}";
exec($cmd, $output);
return $output;
}
// return the oid and pass the array by ref
// or return false on failure
function convert_snmpwalk_line_to_array($line, &$arr) {
if (preg_match('/(.*) = (.*): (.*)/', $line, $matches) === 1) {
$arr = array(
'type' => $matches[2],
'value' => $matches[3],
);
return $matches[1];
}
return false;
}
Now, you can put this in a file in your $USER1$ directory (/usr/local/nagios/libexec) named check_multi_snmpwalk.php and make sure it's executable chmod +x /usr/local/nagios/libexec/check_multi_snmpwalk.php.
Finally, all we need to do is define a command for Nagios to pick it up and use it! Something like the following should suffice:
define command {
command_name check_multi_snmpwalk
command_line $USER1$/check_multi_snmpwalk.php $ARG1$ $ARG2$ $ARG3$ $ARG4$
}
Now you should be able to specify the file you want the JSON to be output to in ARG1, and then each other argument needs to contain the host address, the snmp community, the snmp version and the mib you want to walk.
So, for example:
define service {
host_name localhost
service_description Multi SNMP Walk
use local-service
check_command check_multi_snmpwalk!/tmp/jsonfile!192.168.1.10,community,1,all!192.168.1.11,community,2c,all!!
register 1
}
Now you're saying "Okay, thats all great, but what does it do?!"
I'm glad you asked! This is what it does:
Grabbing some input from the user (what are we snmp walking?)
Executing an snmpwalk (and saving the output) for each host specified
Converting the snmpwalk output to an easy-to-read array
Aggregating each host's snmpwalk easy-to-read array into a giant array
Converting the giant array to JSON
Writing the JSON to the file specified
Returning an OK Status for Nagios with a message stating how many hosts we processed!
A few notes:
This plugin will take a while to run no matter how many hosts you specify, so you may want to consider running it from a cron job instead of a Nagios check
This plugin does NOT conform to the plugin guidelines I linked to earlier, but it was still a fun little project
Hope this helped!
I'm using gettext translations for SF2 and I arrange my translation files in different folder structure than the normal bundle (I kind of created my own mini plugin system for some specific needs).
In any case, this is how I'm loading my translation files:
$finder = new Finder();
$finder->files()->filter(function (\SplFileInfo $file)
{
return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename());
})->in($dirs);
foreach ($finder as $file) {
// filename is domain.locale.format
list($domain, $locale, $format) = explode('.', $file->getBasename(), 3);
// we have to add resource right away or it will be too late
$translator->addResource($format, (string)$file, $locale, $domain);
}
It works well, the only problem is that it is not cached which is not very efficient. I wonder what I should do instead to cache these translation?
My problem was that I forgot the declare translator in the config file and thus the translation pass doesn't work
framework:
translator: { fallback: %locale% }
Where can I get a handle for command line arguments?
eg grunt dist --env=UAT. How do I get the value for env?
While I'm at it, how would I assign a default value to this if it's not set on the command line?
You can use grunt.option() or more specifically:
var env = grunt.option('env') || 'default';
to grab the env argument or default to the string 'default' if the argument is not present.
I find the handling of defaults in grunt to be sorely lacking. The method outlined above works, but it quickly gets tiresome when you have lots of options.
A little helper function can ease this:
function defaultOptions(options) {
for(var key in options) {
if(options.hasOwnProperty(key) && !grunt.option(key)) {
grunt.option(key, options[key]);
}
}
}
You can then use like:
defaultOptions({
env : "staging"
});
And at the CLI:
grunt // { env : "staging" }
grunt --env=UAT // { env : "UAT" }
I'm having no problem creating a share or assigning permissions, but I'm having a really difficult time actually accessing this fully. I'm the administrator on the server, I'm trying to test prepping the server for other users to access and I'm trying to set the permission, for now, to full access to everyone.
The issue is that when I try to create a new file/folder in the share I get access denied.
Does anyone else encounter this error when making shares through powershell?
Here is the code I have been using:
function New-Share
{
param (
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="No folder name specified")]
[string]$FolderName,
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="No share name specified")]
[string]$ShareName,
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$false, HelpMessage="No description specified")]
[string]$Description
)
$error.clear()
# Check for folder; Create it if it doesn't exist
If (!(Test-Path $FolderName))
{
New-Item $FolderName -type Directory | Out-Null
}
# Check for share; Create it if it doesn't exist
$Shares=[WMICLASS]"WIN32_Share"
if (!(Get-WMIObject Win32_share -filter "name='$ShareName'"))
{
$Shares.Create($FolderName,$ShareName,0,65535,$Description) | Out-Null
if (!($error))
{
# Share created
return $true
} else {
# Error
return $false
}
} else {
# Share Exists
return $false
}
}
I've been Invoking the function with this:
function bo.Share()
{
$domain = [Environment]::UserDomainName
$BDrive = "$boDrive" + ":\SYNintviewer"
New-Share -FolderName "$BDrive" -ShareName "SYNintviewer" -Description "SYNintviewer"
}
I actually got this working on my own...
Calling this function instead worked:
function bo.Share()
{
$domain = [Environment]::UserDomainName
$BDrive = "$boDrive" + ":\SYNintviewer"
echo "$boDrive is BoDRIVE"
echo "$BDrive is BDRIVE"
New-Share -Sharename "SYNintviewer" -Sharepath "$BDrive" -group "Authenticated Users" -auth FULL
}
I'm trying to implement the GeocodableBehavior on a Symfony 1.4 (with Propel 1.6) project i'm working on, but until now it's a complete failure. I've tried to search if other people but I didn't found anything, like if I was the only one having troubles with this.
So, maybe I'm missing something very very easy, but following the instructions given on the GeocodableBehavior leads to nothing but errors, and I can't figure out where's the problem.
I followed instructions for the GeocodableBehavior (here -> http://www.propelorm.org/cookbook/geocodable-behavior.html)
This seems to work as i'm getting the latitude/longitude columns created on my model. Until then, it works fine.
Where things get a little more complicated is when trying to save an object with the GeocodableBehavior, there's problems with the Geocoder class.
(Documentation here -> https://github.com/willdurand/Geocoder)
My class is Point, referring to a geolocated point, an address. When creating a Point using sf admin generator, the behavior which is supposed to use some fields (street, postal_code, country, etc) to query the GoogleMaps api, just fails to use the Geocoder class.
Fatal error: Class 'Geocoder\Geocoder' not found in /var/www/vhosts/www._________.local/lib/model/om/BasePoint.php on line 3717
I put the Geocoder class in a lib/vendor/geocoder folder, I tried to use the autoload.yml file to load it, but nothing changes...
autoload:
geocoder:
name: geocoder
path: %SF_LIB_DIR%/vendor/geocoder
recursive: on
There's something i'm missing in how to load those classes in my sf project, and i can't find what. Geocoder package has an autoload.php file but i didn't manage to "load" it successfully...
Thanks in advance.
I know it's kinda giving up on the autoloader, but you could establish a register function in /config/ProjectConfiguration.class.php. The only downside is that you will need to add a call to the function before any block that uses Geocoder.
class ProjectConfiguration extends sfProjectConfiguration
{
static protected $geocoderLoaded = false;
static public function registerGeocoder()
{
if (self::$geocoderLoaded) {
return;
}
require_once sfConfig::get('sf_lib_dir') . '/vendor/geocoder/autoload.php';
self::$geocoderLoaded = true;
}
...
}
Then just execute ProjectConfiguration::registerGeocoder(); anywhere you'd need the class. It's more annoying than getting the autoloader to work, but it's at least dependable.
Did you check your autoload cache to see it there is something related to Geocoder?
/cache/[apps_name]/dev/config/config_autoload.yml.php
/cache/project_autoload.cache
Maybe, manually add the autoload in the /config/ProjectConfiguration.class.php:
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
require_once sfConfig::get('sf_lib_dir').'/vendor/geocoder/src/autoload.php';
Using the built-in autoloader should be a working option, but you can also combine symfony's autoloader with a "PSR-0 enabled" one. Basically, this boils down to the following implementation:
public function setup()
{
// plugin stuff here
// register the new autoloader
spl_autoload_register(array($this, 'autoloadNamespace'));
}
public function autoloadNamespace($className)
{
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strripos($className, '\\'))
{
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
// make sure that the path to Geocoder is correct
foreach(array(
sfConfig::get('sf_lib_dir').'/vendor/Geocoder/src' . DIRECTORY_SEPARATOR . $fileName . $className . '.php',
) as $fileName)
{
if (file_exists($fileName))
{
require $fileName;
return true;
}
}
return false;
}
With this additional autoloader, your application should be able to use Geocoder.