In case somebody's wondering how to achieve this in Magento 2, here is the code (based on @Marius answer above)
<?php namespace Vendor\Module\Setup; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\Catalog\Model\ResourceModel\Product\Action; class InstallData implements InstallDataInterface { /** @var EavSetupFactory */ private $eavSetupFactory; /** @var CollectionFactory */ private $collectionFactory; /** @var Action */ private $action; public function __construct( EavSetupFactory $eavSetupFactory, CollectionFactory $collectionFactory, Action $action ) { $this->eavSetupFactory = $eavSetupFactory; $this->collectionFactory = $collectionFactory; $this->action = $action; } public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); $eavSetup->addAttribute( \Magento\Catalog\Model\Product::ENTITY, 'my_custom_attribute', [ 'type' => 'int', 'frontend' => '', 'frontend_class' => '', 'label' => 'My Custom Attribute', 'input' => 'boolean', 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, 'source' => 'Vendor\Module\Model\Config\Options', 'visible' => true, 'user_defined' => false, 'required' => false, 'default' => '0', 'searchable' => false, 'filterable' => false, 'comparable' => false, 'visible_on_front' => false, 'is_used_in_grid' => true, 'is_visible_in_grid' => true, 'is_filterable_in_grid' => true, 'used_in_product_listing' => false, 'unique' => false, ] ); //set default value for the new custom attribute $productIds = $this->collectionFactory->create()->getAllIds(); $this->action->updateAttributes($productIds, ['my_custom_attribute' => 0], 0); } }